Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/login/wallpaper_manager.h" | 5 #include "chrome/browser/chromeos/login/wallpaper_manager.h" |
| 6 | 6 |
| 7 #include "ash/desktop_background/desktop_background_controller.h" | 7 #include "ash/desktop_background/desktop_background_controller.h" |
| 8 #include "ash/desktop_background/desktop_background_resources.h" | |
| 9 #include "ash/shell.h" | 8 #include "ash/shell.h" |
| 9 #include "base/command_line.h" | |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/file_path.h" | |
| 12 #include "base/file_util.h" | |
| 13 #include "base/path_service.h" | |
| 11 #include "base/string_number_conversions.h" | 14 #include "base/string_number_conversions.h" |
| 15 #include "base/string_util.h" | |
| 12 #include "base/time.h" | 16 #include "base/time.h" |
| 13 #include "base/values.h" | 17 #include "base/values.h" |
| 14 #include "chrome/browser/browser_process.h" | 18 #include "chrome/browser/browser_process.h" |
| 15 #include "chrome/browser/chromeos/login/user_manager.h" | 19 #include "chrome/browser/chromeos/login/user_manager.h" |
| 16 #include "chrome/browser/chromeos/login/user_manager_impl.h" | 20 #include "chrome/browser/chromeos/login/wizard_controller.h" |
| 17 #include "chrome/browser/chromeos/settings/cros_settings.h" | |
| 18 #include "chrome/browser/chromeos/settings/cros_settings.h" | 21 #include "chrome/browser/chromeos/settings/cros_settings.h" |
| 19 #include "chrome/browser/prefs/pref_service.h" | 22 #include "chrome/browser/prefs/pref_service.h" |
| 20 #include "chrome/browser/prefs/scoped_user_pref_update.h" | 23 #include "chrome/browser/prefs/scoped_user_pref_update.h" |
| 24 #include "chrome/common/chrome_notification_types.h" | |
| 25 #include "chrome/common/chrome_paths.h" | |
| 26 #include "chrome/common/chrome_switches.h" | |
| 21 #include "chrome/common/pref_names.h" | 27 #include "chrome/common/pref_names.h" |
| 22 #include "chromeos/dbus/dbus_thread_manager.h" | 28 #include "chromeos/dbus/dbus_thread_manager.h" |
| 23 #include "chromeos/dbus/power_manager_client.h" | 29 #include "chromeos/dbus/power_manager_client.h" |
| 24 #include "content/public/browser/browser_thread.h" | 30 #include "content/public/browser/browser_thread.h" |
| 31 #include "content/public/browser/notification_service.h" | |
| 32 #include "skia/ext/image_operations.h" | |
| 33 #include "ui/gfx/codec/png_codec.h" | |
| 34 #include "ui/gfx/skia_util.h" | |
| 25 | 35 |
| 26 using content::BrowserThread; | 36 using content::BrowserThread; |
| 27 | 37 |
| 28 namespace { | 38 namespace { |
| 29 | 39 |
| 30 const int kWallpaperUpdateIntervalSec = 24 * 60 * 60; | 40 const int kWallpaperUpdateIntervalSec = 24 * 60 * 60; |
| 31 | 41 |
| 42 const char kWallpaperTypeNodeName[] = "type"; | |
| 43 const char kWallpaperIndexNodeName[] = "index"; | |
| 44 const char kWallpaperDateNodeName[] = "date"; | |
| 45 | |
| 46 const int kThumbnailWidth = 128; | |
| 47 const int kThumbnailHeight = 80; | |
| 48 | |
| 49 // Default wallpaper index used in OOBE (first boot). | |
| 50 // Defined here because Chromium default index differs. | |
| 51 // Also see ash::WallpaperInfo kDefaultWallpapers in | |
| 52 // desktop_background_resources.cc | |
| 53 #if defined(GOOGLE_CHROME_BUILD) | |
| 54 const int kDefaultOOBEWallpaperIndex = 16; // IDR_AURA_WALLPAPERS_3_URBAN0 | |
| 55 #else | |
| 56 const int kDefaultOOBEWallpaperIndex = 0; // IDR_AURA_WALLPAPERS_ROMAINGUY_0 | |
| 57 #endif | |
| 58 | |
| 32 // Names of nodes with info about wallpaper. | 59 // Names of nodes with info about wallpaper. |
| 33 const char kWallpaperDateNodeName[] = "date"; | 60 const char kNewWallpaperDateNodeName[] = "date"; |
| 34 const char kWallpaperLayoutNodeName[] = "layout"; | 61 const char kNewWallpaperLayoutNodeName[] = "layout"; |
| 35 const char kWallpaperFileNodeName[] = "file"; | 62 const char kNewWallpaperFileNodeName[] = "file"; |
| 36 const char kWallpaperTypeNodeName[] = "type"; | 63 const char kNewWallpaperTypeNodeName[] = "type"; |
| 37 | 64 |
| 38 } // namespace | 65 } // namespace |
| 39 | 66 |
| 40 namespace chromeos { | 67 namespace chromeos { |
| 41 | 68 |
| 42 static WallpaperManager* g_wallpaper_manager = NULL; | 69 static WallpaperManager* g_wallpaper_manager = NULL; |
| 43 | 70 |
| 44 // WallpaperManager, public: --------------------------------------------------- | 71 // WallpaperManager, public: --------------------------------------------------- |
| 45 | 72 |
| 46 // static | 73 // static |
| 47 WallpaperManager* WallpaperManager::Get() { | 74 WallpaperManager* WallpaperManager::Get() { |
| 48 if (!g_wallpaper_manager) | 75 if (!g_wallpaper_manager) |
| 49 g_wallpaper_manager = new WallpaperManager(); | 76 g_wallpaper_manager = new WallpaperManager(); |
| 50 return g_wallpaper_manager; | 77 return g_wallpaper_manager; |
| 51 } | 78 } |
| 52 | 79 |
| 80 WallpaperManager::WallpaperManager() | |
| 81 : ALLOW_THIS_IN_INITIALIZER_LIST(wallpaper_loader_(new UserImageLoader)), | |
| 82 current_user_wallpaper_type_(User::UNKNOWN), | |
| 83 ALLOW_THIS_IN_INITIALIZER_LIST(current_user_wallpaper_index_( | |
| 84 ash::GetInvalidWallpaperIndex())), | |
| 85 last_selected_user_(""), | |
|
Nikita (slow)
2012/08/02 20:40:26
not needed
bshe
2012/08/02 21:59:28
Done.
| |
| 86 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { | |
| 87 RestartTimer(); | |
| 88 registrar_.Add(this, | |
| 89 chrome::NOTIFICATION_LOGIN_USER_CHANGED, | |
| 90 content::NotificationService::AllSources()); | |
| 91 } | |
| 92 | |
| 53 // static | 93 // static |
| 54 void WallpaperManager::RegisterPrefs(PrefService* local_state) { | 94 void WallpaperManager::RegisterPrefs(PrefService* local_state) { |
| 55 local_state->RegisterDictionaryPref(prefs::kUsersWallpaperInfo, | 95 local_state->RegisterDictionaryPref(prefs::kUsersWallpaperInfo, |
| 56 PrefService::UNSYNCABLE_PREF); | 96 PrefService::UNSYNCABLE_PREF); |
| 57 } | 97 } |
| 58 | 98 |
| 59 WallpaperManager::WallpaperManager() : last_selected_user_("") { | 99 void WallpaperManager::AddObservers() { |
| 100 if (!DBusThreadManager::Get()->GetPowerManagerClient()->HasObserver(this)) | |
| 101 DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this); | |
| 60 system::TimezoneSettings::GetInstance()->AddObserver(this); | 102 system::TimezoneSettings::GetInstance()->AddObserver(this); |
| 61 RestartTimer(); | |
| 62 } | 103 } |
| 63 | 104 |
| 64 void WallpaperManager::AddPowerManagerClientObserver() { | 105 void WallpaperManager::CacheIfCustomWallpaper(const std::string& email) { |
| 65 if (!DBusThreadManager::Get()->GetPowerManagerClient()->HasObserver(this)) | 106 User::WallpaperType type; |
| 66 DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this); | 107 int index; |
| 108 base::Time date; | |
| 109 GetUserWallpaperProperties(email, &type, &index, &date); | |
| 110 if (type == User::CUSTOMIZED) { | |
| 111 std::string wallpaper_path = GetWallpaperPathForUser(email, false).value(); | |
| 112 | |
| 113 // Uses WeakPtr here to make the request cancelable. | |
| 114 wallpaper_loader_->Start(wallpaper_path, 0, true, | |
| 115 base::Bind(&WallpaperManager::CacheWallpaper, | |
| 116 weak_factory_.GetWeakPtr(), email)); | |
| 117 } | |
| 118 } | |
| 119 | |
| 120 void WallpaperManager::EnsureLoggedInUserWallpaperLoaded() { | |
| 121 User::WallpaperType type; | |
| 122 int index; | |
| 123 base::Time last_modification_date; | |
| 124 GetLoggedInUserWallpaperProperties(&type, &index, &last_modification_date); | |
| 125 | |
| 126 if (type != current_user_wallpaper_type_ || | |
| 127 index != current_user_wallpaper_index_) { | |
| 128 SetUserWallpaper(UserManager::Get()->GetLoggedInUser().email()); | |
| 129 } | |
| 130 } | |
| 131 | |
| 132 void WallpaperManager::FetchCustomWallpaper(const std::string& email) { | |
| 133 User::WallpaperType type; | |
| 134 int index; | |
| 135 base::Time date; | |
| 136 GetUserWallpaperProperties(email, &type, &index, &date); | |
| 137 ash::WallpaperLayout layout = static_cast<ash::WallpaperLayout>(index); | |
| 138 | |
| 139 std::string wallpaper_path = GetWallpaperPathForUser(email, false).value(); | |
| 140 | |
| 141 wallpaper_loader_->Start(wallpaper_path, 0, true, | |
| 142 base::Bind(&WallpaperManager::FetchWallpaper, | |
| 143 base::Unretained(this), email, layout)); | |
| 144 } | |
| 145 | |
| 146 bool WallpaperManager::GetCustomWallpaperFromCache(const std::string& email, | |
| 147 gfx::ImageSkia* wallpaper) { | |
| 148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 149 CustomWallpaperMap::const_iterator it = custom_wallpaper_cache_.find(email); | |
| 150 if (it != custom_wallpaper_cache_.end()) { | |
| 151 *wallpaper = (*it).second; | |
| 152 return true; | |
| 153 } | |
| 154 return false; | |
| 155 } | |
| 156 | |
| 157 FilePath WallpaperManager::GetWallpaperPathForUser(const std::string& username, | |
| 158 bool is_thumbnail) { | |
| 159 std::string filename = username + | |
|
Nikita (slow)
2012/08/02 20:40:26
nit: use StringPrintf and 2 format strings?
bshe
2012/08/02 21:59:28
Used StringPrintf. But I am not sure if I am doing
| |
| 160 (is_thumbnail ? "_wallpaper_thumb.png" : "_wallpaper.png"); | |
| 161 FilePath user_data_dir; | |
| 162 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); | |
| 163 return user_data_dir.AppendASCII(filename); | |
| 164 } | |
| 165 | |
| 166 gfx::ImageSkia WallpaperManager::GetCustomWallpaperThumbnail( | |
| 167 const std::string& email) { | |
| 168 CustomWallpaperMap::const_iterator it = | |
| 169 custom_wallpaper_thumbnail_cache_.find(email); | |
| 170 if (it != custom_wallpaper_cache_.end()) | |
| 171 return (*it).second; | |
| 172 else | |
| 173 return gfx::ImageSkia(); | |
| 174 } | |
| 175 | |
| 176 void WallpaperManager::GetLoggedInUserWallpaperProperties( | |
| 177 User::WallpaperType* type, | |
| 178 int* index, | |
| 179 base::Time* last_modification_date) { | |
| 180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 181 | |
| 182 if (UserManager::Get()->IsLoggedInAsStub()) { | |
| 183 *type = current_user_wallpaper_type_ = User::DEFAULT; | |
| 184 *index = current_user_wallpaper_index_ = ash::GetInvalidWallpaperIndex(); | |
| 185 return; | |
| 186 } | |
| 187 | |
| 188 GetUserWallpaperProperties(UserManager::Get()->GetLoggedInUser().email(), | |
| 189 type, index, last_modification_date); | |
| 190 } | |
| 191 | |
| 192 void WallpaperManager::InitializeWallpaper() { | |
| 193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 194 UserManager* user_manager = UserManager::Get(); | |
| 195 if (!user_manager->IsUserLoggedIn()) { | |
| 196 if (!CommandLine::ForCurrentProcess()->HasSwitch( | |
| 197 switches::kDisableNewOobe)) { | |
| 198 if (!WizardController::IsDeviceRegistered() && | |
| 199 !WizardController::IsZeroDelayEnabled()) { | |
| 200 // TODO(nkostylev): Add switch to disable wallpaper transition on OOBE. | |
| 201 // Should be used on test images so that they are not slowed down. | |
| 202 ash::Shell::GetInstance()->desktop_background_controller()-> | |
| 203 SetDefaultWallpaper(kDefaultOOBEWallpaperIndex); | |
| 204 } else { | |
| 205 bool show_users = true; | |
| 206 bool result = CrosSettings::Get()->GetBoolean( | |
| 207 kAccountsPrefShowUserNamesOnSignIn, &show_users); | |
| 208 DCHECK(result) << "Unable to fetch setting " | |
| 209 << kAccountsPrefShowUserNamesOnSignIn; | |
| 210 if (!show_users) { | |
| 211 ash::Shell::GetInstance()->desktop_background_controller()-> | |
| 212 SetDefaultWallpaper(ash::GetSolidColorIndex()); | |
| 213 } | |
| 214 } | |
| 215 } | |
| 216 return; | |
| 217 } | |
| 218 SetUserWallpaper(user_manager->GetLoggedInUser().email()); | |
| 219 } | |
| 220 | |
| 221 void WallpaperManager::Observe(int type, | |
| 222 const content::NotificationSource& source, | |
| 223 const content::NotificationDetails& details) { | |
| 224 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 225 if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED) { | |
| 226 // Cancel callback for previous cache requests. | |
| 227 weak_factory_.InvalidateWeakPtrs(); | |
| 228 custom_wallpaper_cache_.clear(); | |
| 229 } | |
| 67 } | 230 } |
| 68 | 231 |
| 69 void WallpaperManager::RestartTimer() { | 232 void WallpaperManager::RestartTimer() { |
| 70 timer_.Stop(); | 233 timer_.Stop(); |
| 71 base::Time midnight = base::Time::Now().LocalMidnight(); | 234 base::Time midnight = base::Time::Now().LocalMidnight(); |
| 72 base::TimeDelta interval = base::Time::Now() - midnight; | 235 base::TimeDelta interval = base::Time::Now() - midnight; |
| 73 int64 remaining_seconds = kWallpaperUpdateIntervalSec - interval.InSeconds(); | 236 int64 remaining_seconds = kWallpaperUpdateIntervalSec - interval.InSeconds(); |
| 74 if (remaining_seconds <= 0) { | 237 if (remaining_seconds <= 0) { |
| 75 BatchUpdateWallpaper(); | 238 BatchUpdateWallpaper(); |
| 76 } else { | 239 } else { |
| 77 // Set up a one shot timer which will batch update wallpaper at midnight. | 240 // Set up a one shot timer which will batch update wallpaper at midnight. |
| 78 timer_.Start(FROM_HERE, | 241 timer_.Start(FROM_HERE, |
| 79 base::TimeDelta::FromSeconds(remaining_seconds), | 242 base::TimeDelta::FromSeconds(remaining_seconds), |
| 80 this, | 243 this, |
| 81 &WallpaperManager::BatchUpdateWallpaper); | 244 &WallpaperManager::BatchUpdateWallpaper); |
| 82 } | 245 } |
| 83 } | 246 } |
| 84 | 247 |
| 248 void WallpaperManager::SaveUserWallpaperProperties(const std::string& email, | |
| 249 User::WallpaperType type, | |
| 250 int index) { | |
| 251 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 252 | |
| 253 current_user_wallpaper_type_ = type; | |
| 254 current_user_wallpaper_index_ = index; | |
| 255 // Ephemeral users can not save data to local state. We just cache the index | |
| 256 // in memory for them. | |
| 257 if (UserManager::Get()->IsCurrentUserEphemeral()) { | |
|
Nikita (slow)
2012/08/02 20:40:26
nit: drop {}
bshe
2012/08/02 21:59:28
Done.
| |
| 258 return; | |
| 259 } | |
| 260 | |
| 261 PrefService* local_state = g_browser_process->local_state(); | |
| 262 DictionaryPrefUpdate wallpaper_update(local_state, | |
| 263 UserManager::kUserWallpapersProperties); | |
| 264 | |
| 265 base::DictionaryValue* wallpaper_properties = new base::DictionaryValue(); | |
| 266 wallpaper_properties->Set(kWallpaperTypeNodeName, | |
| 267 new base::FundamentalValue(type)); | |
| 268 wallpaper_properties->Set(kWallpaperIndexNodeName, | |
| 269 new base::FundamentalValue(index)); | |
| 270 wallpaper_properties->SetString(kWallpaperDateNodeName, | |
| 271 base::Int64ToString(base::Time::Now().LocalMidnight().ToInternalValue())); | |
| 272 wallpaper_update->SetWithoutPathExpansion(email, wallpaper_properties); | |
| 273 } | |
| 274 | |
| 275 void WallpaperManager::SetUserWallpaperFromFile( | |
| 276 const std::string& username, | |
| 277 const FilePath& path, | |
| 278 ash::WallpaperLayout layout, | |
| 279 base::WeakPtr<WallpaperDelegate> delegate) { | |
| 280 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 281 | |
| 282 // For wallpapers, save the image without resizing. | |
| 283 wallpaper_loader_->Start( | |
| 284 path.value(), 0, true, | |
| 285 base::Bind(&WallpaperManager::SetWallpaper, | |
| 286 base::Unretained(this), username, layout, User::CUSTOMIZED, | |
| 287 delegate)); | |
| 288 } | |
| 289 | |
| 290 void WallpaperManager::SetInitialUserWallpaper(const std::string& username) { | |
| 291 current_user_wallpaper_type_ = User::DEFAULT; | |
| 292 // TODO(bshe): Ideally, wallpaper should start to load as soon as user click | |
|
Nikita (slow)
2012/08/02 20:40:26
Could you please clarify this comment?
Is this abo
bshe
2012/08/02 21:59:28
It is not about the timeout we have.
When a new u
Nikita (slow)
2012/08/02 22:52:57
Yes, when we click AddUser we need to load default
bshe
2012/08/03 00:23:35
Done.
| |
| 293 // "Add user". | |
| 294 if (username == kGuestUser) | |
| 295 current_user_wallpaper_index_ = ash::GetGuestWallpaperIndex(); | |
| 296 else | |
| 297 current_user_wallpaper_index_ = ash::GetDefaultWallpaperIndex(); | |
| 298 SaveUserWallpaperProperties(username, | |
| 299 current_user_wallpaper_type_, | |
| 300 current_user_wallpaper_index_); | |
| 301 | |
| 302 // Some browser tests do not have shell instance. And it is not necessary to | |
| 303 // create a wallpaper for these tests. Add HasInstance check to prevent tests | |
| 304 // crash and speed up the tests by avoid loading wallpaper. | |
| 305 if (ash::Shell::HasInstance()) { | |
| 306 ash::Shell::GetInstance()->desktop_background_controller()-> | |
| 307 SetDefaultWallpaper(current_user_wallpaper_index_); | |
| 308 } | |
| 309 } | |
| 310 | |
| 85 void WallpaperManager::SaveUserWallpaperInfo(const std::string& username, | 311 void WallpaperManager::SaveUserWallpaperInfo(const std::string& username, |
| 86 const std::string& file_name, | 312 const std::string& file_name, |
| 87 ash::WallpaperLayout layout, | 313 ash::WallpaperLayout layout, |
| 88 User::WallpaperType type) { | 314 User::WallpaperType type) { |
| 89 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 315 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 90 | 316 |
| 91 // Ephemeral users can not save data to local state. We just cache the index | 317 // Ephemeral users can not save data to local state. We just cache the index |
| 92 // in memory for them. | 318 // in memory for them. |
| 93 if (UserManager::Get()->IsCurrentUserEphemeral()) | 319 if (UserManager::Get()->IsCurrentUserEphemeral()) |
| 94 return; | 320 return; |
| 95 | 321 |
| 96 PrefService* local_state = g_browser_process->local_state(); | 322 PrefService* local_state = g_browser_process->local_state(); |
| 97 DictionaryPrefUpdate wallpaper_update(local_state, | 323 DictionaryPrefUpdate wallpaper_update(local_state, |
| 98 prefs::kUsersWallpaperInfo); | 324 prefs::kUsersWallpaperInfo); |
| 99 | 325 |
| 100 base::DictionaryValue* wallpaper_properties = new base::DictionaryValue(); | 326 base::DictionaryValue* wallpaper_properties = new base::DictionaryValue(); |
| 101 wallpaper_properties->SetString(kWallpaperDateNodeName, | 327 wallpaper_properties->SetString(kNewWallpaperDateNodeName, |
| 102 base::Int64ToString(base::Time::Now().LocalMidnight().ToInternalValue())); | 328 base::Int64ToString(base::Time::Now().LocalMidnight().ToInternalValue())); |
| 103 wallpaper_properties->SetString(kWallpaperFileNodeName, file_name); | 329 wallpaper_properties->SetString(kNewWallpaperFileNodeName, file_name); |
| 104 wallpaper_properties->SetInteger(kWallpaperLayoutNodeName, layout); | 330 wallpaper_properties->SetInteger(kNewWallpaperLayoutNodeName, layout); |
| 105 wallpaper_properties->SetInteger(kWallpaperTypeNodeName, type); | 331 wallpaper_properties->SetInteger(kNewWallpaperTypeNodeName, type); |
| 106 wallpaper_update->SetWithoutPathExpansion(username, wallpaper_properties); | 332 wallpaper_update->SetWithoutPathExpansion(username, wallpaper_properties); |
| 107 } | 333 } |
| 108 | 334 |
| 109 void WallpaperManager::SetLastSelectedUser( | 335 void WallpaperManager::SetLastSelectedUser( |
| 110 const std::string& last_selected_user) { | 336 const std::string& last_selected_user) { |
| 111 last_selected_user_ = last_selected_user; | 337 last_selected_user_ = last_selected_user; |
| 112 } | 338 } |
| 113 | 339 |
| 340 void WallpaperManager::SetUserWallpaper(const std::string& email) { | |
| 341 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 342 if (UserManager::Get()->IsKnownUser(email)) { | |
|
Nikita (slow)
2012/08/02 20:40:26
Simplify with
if (!UserManager::Get()->IsKnownUse
bshe
2012/08/02 21:59:28
Done.
| |
| 343 User::WallpaperType type; | |
| 344 int index; | |
| 345 base::Time date; | |
| 346 GetUserWallpaperProperties(email, &type, &index, &date); | |
| 347 if (type == User::DAILY && date != base::Time::Now().LocalMidnight()) { | |
| 348 index = ash::GetNextWallpaperIndex(index); | |
| 349 SaveUserWallpaperProperties(email, User::DAILY, index); | |
| 350 } else if (type == User::CUSTOMIZED) { | |
| 351 gfx::ImageSkia custom_wallpaper; | |
| 352 if (GetCustomWallpaperFromCache(email, &custom_wallpaper)) { | |
| 353 // In customized mode, we use index pref to save the user selected | |
| 354 // wallpaper layout. See function SaveWallpaperToLocalState(). | |
| 355 ash::WallpaperLayout layout = static_cast<ash::WallpaperLayout>(index); | |
| 356 ash::Shell::GetInstance()->desktop_background_controller()-> | |
| 357 SetCustomWallpaper(custom_wallpaper, layout); | |
| 358 } else { | |
| 359 FetchCustomWallpaper(email); | |
| 360 } | |
| 361 return; | |
| 362 } | |
| 363 ash::Shell::GetInstance()->desktop_background_controller()-> | |
| 364 SetDefaultWallpaper(index); | |
| 365 SetLastSelectedUser(email); | |
| 366 } | |
| 367 } | |
| 368 | |
| 114 void WallpaperManager::SetWallpaperFromFilePath(const std::string& path, | 369 void WallpaperManager::SetWallpaperFromFilePath(const std::string& path, |
| 115 ash::WallpaperLayout layout) { | 370 ash::WallpaperLayout layout) { |
| 116 image_loader_->Start( | 371 image_loader_->Start( |
| 117 path, 0, false, | 372 path, 0, false, |
| 118 base::Bind(&WallpaperManager::OnWallpaperLoaded, | 373 base::Bind(&WallpaperManager::OnWallpaperLoaded, |
| 119 base::Unretained(this), layout)); | 374 base::Unretained(this), layout)); |
| 120 } | 375 } |
| 121 | 376 |
| 122 void WallpaperManager::SetWallpaperFromImageSkia( | 377 void WallpaperManager::SetWallpaperFromImageSkia( |
| 123 const gfx::ImageSkia& wallpaper, | 378 const gfx::ImageSkia& wallpaper, |
| 124 ash::WallpaperLayout layout) { | 379 ash::WallpaperLayout layout) { |
| 125 ash::Shell::GetInstance()->desktop_background_controller()-> | 380 ash::Shell::GetInstance()->desktop_background_controller()-> |
| 126 SetCustomWallpaper(wallpaper, layout); | 381 SetCustomWallpaper(wallpaper, layout); |
| 127 } | 382 } |
| 128 | 383 |
| 129 void WallpaperManager::UserDeselected() { | 384 void WallpaperManager::OnUserDeselected() { |
| 130 if (!UserManager::Get()->IsUserLoggedIn()) { | 385 if (!UserManager::Get()->IsUserLoggedIn()) { |
| 131 // This will set default login wallpaper (#fefefe). | 386 // This will set default login wallpaper (#fefefe). |
| 132 ash::Shell::GetInstance()->desktop_background_controller()-> | 387 ash::Shell::GetInstance()->desktop_background_controller()-> |
| 133 SetDefaultWallpaper(ash::GetSolidColorIndex()); | 388 SetDefaultWallpaper(ash::GetSolidColorIndex()); |
| 134 } | 389 } |
| 135 } | 390 } |
| 136 | 391 |
| 392 void WallpaperManager::OnUserSelected(const std::string& email) { | |
| 393 SetUserWallpaper(email); | |
| 394 } | |
| 395 | |
| 137 // WallpaperManager, private: -------------------------------------------------- | 396 // WallpaperManager, private: -------------------------------------------------- |
| 138 | 397 |
| 139 WallpaperManager::~WallpaperManager() { | 398 WallpaperManager::~WallpaperManager() { |
| 140 DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this); | 399 DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this); |
| 141 system::TimezoneSettings::GetInstance()->RemoveObserver(this); | 400 system::TimezoneSettings::GetInstance()->RemoveObserver(this); |
| 142 } | 401 } |
| 143 | 402 |
| 144 void WallpaperManager::OnCustomWallpaperLoaded(const std::string& email, | 403 void WallpaperManager::OnCustomWallpaperLoaded(const std::string& email, |
| 145 ash::WallpaperLayout layout, | 404 ash::WallpaperLayout layout, |
| 146 const UserImage& user_image) { | 405 const UserImage& user_image) { |
| 147 const SkBitmap& wallpaper = user_image.image(); | 406 const gfx::ImageSkia& wallpaper = user_image.image(); |
| 148 ash::Shell::GetInstance()->desktop_background_controller()-> | 407 ash::Shell::GetInstance()->desktop_background_controller()-> |
| 149 SetCustomWallpaper(wallpaper, layout); | 408 SetCustomWallpaper(wallpaper, layout); |
| 150 } | 409 } |
| 151 | 410 |
| 152 void WallpaperManager::BatchUpdateWallpaper() { | 411 void WallpaperManager::BatchUpdateWallpaper() { |
| 153 PrefService* local_state = g_browser_process->local_state(); | 412 PrefService* local_state = g_browser_process->local_state(); |
| 154 UserManager* user_manager = UserManager::Get(); | 413 UserManager* user_manager = UserManager::Get(); |
| 155 bool show_users = true; | 414 bool show_users = true; |
| 156 CrosSettings::Get()->GetBoolean( | 415 CrosSettings::Get()->GetBoolean( |
| 157 kAccountsPrefShowUserNamesOnSignIn, &show_users); | 416 kAccountsPrefShowUserNamesOnSignIn, &show_users); |
| 158 if (local_state) { | 417 if (local_state) { |
| 159 User::WallpaperType type; | 418 User::WallpaperType type; |
| 160 int index = 0; | 419 int index = 0; |
| 161 base::Time last_modification_date; | 420 base::Time last_modification_date; |
| 162 const UserList& users = user_manager->GetUsers(); | 421 const UserList& users = user_manager->GetUsers(); |
| 163 for (UserList::const_iterator it = users.begin(); | 422 for (UserList::const_iterator it = users.begin(); |
| 164 it != users.end(); ++it) { | 423 it != users.end(); ++it) { |
| 165 std::string email = (*it)->email(); | 424 std::string email = (*it)->email(); |
| 166 // TODO(bshe): Move GetUserWallpaperProperties() to this class. | 425 GetUserWallpaperProperties(email, &type, &index, &last_modification_date); |
| 167 static_cast<UserManagerImpl*>(user_manager)-> | |
| 168 GetUserWallpaperProperties(email, &type, &index, | |
| 169 &last_modification_date); | |
| 170 base::Time current_date = base::Time::Now().LocalMidnight(); | 426 base::Time current_date = base::Time::Now().LocalMidnight(); |
| 171 if (type == User::DAILY && current_date != last_modification_date) { | 427 if (type == User::DAILY && current_date != last_modification_date) { |
| 172 index = ash::GetNextWallpaperIndex(index); | 428 index = ash::GetNextWallpaperIndex(index); |
| 173 // TODO(bshe): Move SaveUserWallpaperProperties() to this class. | 429 SaveUserWallpaperProperties(email, type, index); |
| 174 static_cast<UserManagerImpl*>(user_manager)-> | |
| 175 SaveUserWallpaperProperties(email, type, index); | |
| 176 } | 430 } |
| 177 // Force a wallpaper update for logged in / last selected user. | 431 // Force a wallpaper update for logged in / last selected user. |
| 178 // TODO(bshe): Notify lock screen, wallpaper picker UI to update wallpaper | 432 // TODO(bshe): Notify lock screen, wallpaper picker UI to update wallpaper |
| 179 // as well. | 433 // as well. |
| 180 if (user_manager->IsUserLoggedIn() && | 434 if (user_manager->IsUserLoggedIn() && |
| 181 email == user_manager->GetLoggedInUser().email()) { | 435 email == user_manager->GetLoggedInUser().email()) { |
| 182 user_manager->UserSelected(email); | 436 SetUserWallpaper(email); |
| 183 } else if (show_users && | 437 } else if (show_users && |
| 184 email == last_selected_user_) { | 438 email == last_selected_user_) { |
| 185 user_manager->UserSelected(email); | 439 SetUserWallpaper(email); |
| 186 } | 440 } |
| 187 } | 441 } |
| 188 } | 442 } |
| 189 RestartTimer(); | 443 RestartTimer(); |
| 190 } | 444 } |
| 191 | 445 |
| 446 void WallpaperManager::CacheWallpaper(const std::string& email, | |
| 447 const UserImage& wallpaper) { | |
| 448 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 449 DCHECK(custom_wallpaper_cache_.find(email) == custom_wallpaper_cache_.end()); | |
| 450 | |
| 451 BrowserThread::PostTask( | |
| 452 BrowserThread::FILE, | |
| 453 FROM_HERE, | |
| 454 base::Bind(&WallpaperManager::CacheThumbnail, | |
| 455 base::Unretained(this), email, wallpaper.image())); | |
| 456 | |
| 457 custom_wallpaper_cache_.insert(std::make_pair(email, wallpaper.image())); | |
| 458 } | |
| 459 | |
| 460 void WallpaperManager::CacheThumbnail(const std::string& email, | |
| 461 const gfx::ImageSkia& wallpaper) { | |
| 462 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
| 463 gfx::ImageSkia thumbnail = | |
| 464 skia::ImageOperations::Resize(wallpaper, | |
|
Nikita (slow)
2012/08/02 20:40:26
Doesn't seem like FILE thread is a right place for
Nikita (slow)
2012/08/02 20:40:26
Why thumbnail for custom wallpaper is not loaded f
bshe
2012/08/02 21:59:28
Since we always have the large size wallpaper load
Nikita (slow)
2012/08/02 22:52:57
Usually they should be done on WorkerPool (intensi
| |
| 465 skia::ImageOperations::RESIZE_LANCZOS3, | |
| 466 kThumbnailWidth, kThumbnailHeight); | |
| 467 custom_wallpaper_thumbnail_cache_[email] = thumbnail; | |
| 468 } | |
| 469 | |
| 470 void WallpaperManager::FetchWallpaper(const std::string& email, | |
| 471 ash::WallpaperLayout layout, | |
| 472 const UserImage& wallpaper) { | |
| 473 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 474 | |
| 475 BrowserThread::PostTask( | |
| 476 BrowserThread::FILE, | |
| 477 FROM_HERE, | |
| 478 base::Bind(&WallpaperManager::CacheThumbnail, | |
| 479 base::Unretained(this), email, wallpaper.image())); | |
| 480 | |
| 481 ash::Shell::GetInstance()->desktop_background_controller()-> | |
| 482 SetCustomWallpaper(wallpaper.image(), layout); | |
| 483 } | |
| 484 | |
| 485 void WallpaperManager::GetUserWallpaperProperties(const std::string& email, | |
| 486 User::WallpaperType* type, | |
| 487 int* index, | |
| 488 base::Time* last_modification_date) { | |
| 489 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 490 | |
| 491 // Default to the values cached in memory. | |
| 492 *type = current_user_wallpaper_type_; | |
| 493 *index = current_user_wallpaper_index_; | |
| 494 | |
| 495 // Override with values found in local store, if any. | |
| 496 if (!email.empty()) { | |
| 497 const DictionaryValue* user_wallpapers = g_browser_process->local_state()-> | |
| 498 GetDictionary(UserManager::kUserWallpapersProperties); | |
| 499 const base::DictionaryValue* wallpaper_properties; | |
| 500 if (user_wallpapers->GetDictionaryWithoutPathExpansion( | |
| 501 email, | |
| 502 &wallpaper_properties)) { | |
| 503 *type = User::UNKNOWN; | |
| 504 *index = ash::GetInvalidWallpaperIndex(); | |
| 505 wallpaper_properties->GetInteger(kWallpaperTypeNodeName, | |
| 506 reinterpret_cast<int*>(type)); | |
| 507 wallpaper_properties->GetInteger(kWallpaperIndexNodeName, index); | |
| 508 std::string date_string; | |
| 509 int64 val; | |
| 510 if (!(wallpaper_properties->GetString(kWallpaperDateNodeName, | |
| 511 &date_string) && | |
| 512 base::StringToInt64(date_string, &val))) | |
| 513 val = 0; | |
| 514 *last_modification_date = base::Time::FromInternalValue(val); | |
| 515 } | |
| 516 } | |
| 517 } | |
| 518 | |
| 519 void WallpaperManager::GenerateUserWallpaperThumbnail( | |
| 520 const std::string& email, | |
| 521 User::WallpaperType type, | |
| 522 base::WeakPtr<WallpaperDelegate> delegate, | |
| 523 const gfx::ImageSkia& wallpaper) { | |
| 524 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
| 525 gfx::ImageSkia thumbnail = | |
| 526 skia::ImageOperations::Resize(wallpaper, | |
|
Nikita (slow)
2012/08/02 20:40:26
Doesn't seem like a right thread to do a resize.
| |
| 527 skia::ImageOperations::RESIZE_LANCZOS3, | |
| 528 kThumbnailWidth, kThumbnailHeight); | |
| 529 | |
| 530 custom_wallpaper_thumbnail_cache_[email] = thumbnail; | |
| 531 | |
| 532 // Notify thumbnail is ready. | |
| 533 BrowserThread::PostTask( | |
| 534 BrowserThread::UI, | |
| 535 FROM_HERE, | |
| 536 base::Bind(&WallpaperManager::OnThumbnailUpdated, | |
| 537 base::Unretained(this), delegate)); | |
| 538 } | |
| 539 | |
| 540 void WallpaperManager::OnThumbnailUpdated( | |
| 541 base::WeakPtr<WallpaperDelegate> delegate) { | |
| 542 if (delegate) | |
| 543 delegate->SetCustomWallpaperThumbnail(); | |
| 544 } | |
| 545 | |
| 546 void WallpaperManager::SaveWallpaper(const std::string& path, | |
| 547 const UserImage& wallpaper) { | |
| 548 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | |
| 549 std::vector<unsigned char> image_data = wallpaper.raw_image(); | |
| 550 int write_bytes = file_util::WriteFile(FilePath(path), | |
| 551 reinterpret_cast<char*>(&*image_data.begin()), | |
| 552 image_data.size()); | |
| 553 DCHECK(write_bytes == static_cast<int>(image_data.size())); | |
| 554 } | |
| 555 | |
| 556 void WallpaperManager::SetWallpaper(const std::string& username, | |
| 557 ash::WallpaperLayout layout, | |
| 558 User::WallpaperType type, | |
| 559 base::WeakPtr<WallpaperDelegate> delegate, | |
| 560 const UserImage& wallpaper) { | |
| 561 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 562 | |
| 563 std::string wallpaper_path = | |
| 564 GetWallpaperPathForUser(username, false).value(); | |
| 565 | |
| 566 // TODO(bshe): Ephemeral user should not save custom wallpaper to disk. | |
| 567 BrowserThread::PostTask( | |
| 568 BrowserThread::FILE, | |
| 569 FROM_HERE, | |
| 570 base::Bind(&WallpaperManager::SaveWallpaper, | |
| 571 base::Unretained(this), wallpaper_path, wallpaper)); | |
| 572 | |
| 573 BrowserThread::PostTask( | |
| 574 BrowserThread::FILE, | |
| 575 FROM_HERE, | |
| 576 base::Bind(&WallpaperManager::GenerateUserWallpaperThumbnail, | |
| 577 base::Unretained(this), username, type, delegate, | |
| 578 wallpaper.image())); | |
| 579 | |
| 580 ash::Shell::GetInstance()->desktop_background_controller()-> | |
| 581 SetCustomWallpaper(wallpaper.image(), layout); | |
| 582 SaveUserWallpaperProperties(username, type, layout); | |
| 583 } | |
| 584 | |
| 192 void WallpaperManager::OnWallpaperLoaded(ash::WallpaperLayout layout, | 585 void WallpaperManager::OnWallpaperLoaded(ash::WallpaperLayout layout, |
| 193 const UserImage& user_image) { | 586 const UserImage& user_image) { |
| 194 const SkBitmap& wallpaper = user_image.image(); | 587 const SkBitmap& wallpaper = user_image.image(); |
| 195 SetWallpaperFromImageSkia(wallpaper, layout); | 588 SetWallpaperFromImageSkia(wallpaper, layout); |
| 196 } | 589 } |
| 197 | 590 |
| 198 void WallpaperManager::SystemResumed() { | 591 void WallpaperManager::SystemResumed() { |
| 199 BatchUpdateWallpaper(); | 592 BatchUpdateWallpaper(); |
| 200 } | 593 } |
| 201 | 594 |
| 202 void WallpaperManager::TimezoneChanged(const icu::TimeZone& timezone) { | 595 void WallpaperManager::TimezoneChanged(const icu::TimeZone& timezone) { |
| 203 RestartTimer(); | 596 RestartTimer(); |
| 204 } | 597 } |
| 205 | 598 |
| 206 } // chromeos | 599 } // chromeos |
| OLD | NEW |