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