1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <numeric>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ash/ash_constants.h"
11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ash/ash_switches.h"
12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ash/desktop_background/desktop_background_controller.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h"
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/bind.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/debug/trace_event.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/files/file_enumerator.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_registry_simple.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/prefs/scoped_user_pref_update.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
275e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
285e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h"
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/sys_info.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/worker_pool.h"
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "chrome/browser/chromeos/customization_document.h"
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/login/startup_utils.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/login/wizard_controller.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/settings/cros_settings.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
42b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chromeos/chromeos_switches.h"
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chromeos/cryptohome/async_method_caller.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h"
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chromeos/login/user_names.h"
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/user_manager/user.h"
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/user_manager/user_image/user_image.h"
486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/user_manager/user_manager.h"
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/user_manager/user_type.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "third_party/skia/include/core/SkColor.h"
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/codec/jpeg_codec.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia_operations.h"
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/skia_util.h"
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
59c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochnamespace chromeos {
60c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// The amount of delay before starts to move custom wallpapers to the new place.
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const int kMoveCustomWallpaperDelaySeconds = 30;
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Default quality for encoding wallpaper.
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kDefaultEncodingQuality = 90;
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A dictionary pref that maps usernames to file paths to their wallpapers.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Deprecated. Will remove this const char after done migration.
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUserWallpapers[] = "UserWallpapers";
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kCacheWallpaperDelayMs = 500;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A dictionary pref that maps usernames to wallpaper properties.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUserWallpapersProperties[] = "UserWallpapersProperties";
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Names of nodes with info about wallpaper in |kUserWallpapersProperties|
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// dictionary.
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kNewWallpaperDateNodeName[] = "date";
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kNewWallpaperLayoutNodeName[] = "layout";
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kNewWallpaperLocationNodeName[] = "file";
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kNewWallpaperTypeNodeName[] = "type";
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Maximum number of wallpapers cached by CacheUsersWallpapers().
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kMaxWallpapersToCache = 3;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Maximum number of entries in WallpaperManager::last_load_times_ .
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const size_t kLastLoadsStatsMsMaxSize = 4;
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Minimum delay between wallpaper loads, milliseconds.
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const unsigned kLoadMinDelayMs = 50;
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Default wallpaper load delay, milliseconds.
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const unsigned kLoadDefaultDelayMs = 200;
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Maximum wallpaper load delay, milliseconds.
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const unsigned kLoadMaxDelayMs = 2000;
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// When no wallpaper image is specified, the screen is filled with a solid
101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// color.
102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const SkColor kDefaultWallpaperColor = SK_ColorGRAY;
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For our scaling ratios we need to round positive numbers.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int RoundPositive(double x) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<int>(floor(x + 0.5));
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Returns custom wallpaper directory by appending corresponding |sub_dir|.
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)base::FilePath GetCustomWallpaperDir(const char* sub_dir) {
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath custom_wallpaper_dir;
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CHECK(PathService::Get(chrome::DIR_CHROMEOS_CUSTOM_WALLPAPERS,
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         &custom_wallpaper_dir));
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return custom_wallpaper_dir.Append(sub_dir);
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool MoveCustomWallpaperDirectory(const char* sub_dir,
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  const std::string& user_id,
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                  const std::string& user_id_hash) {
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::FilePath base_path = GetCustomWallpaperDir(sub_dir);
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::FilePath to_path = base_path.Append(user_id_hash);
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::FilePath from_path = base_path.Append(user_id);
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (base::PathExists(from_path))
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return base::Move(from_path, to_path);
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return false;
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// These global default values are used to set customized default
1290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// wallpaper path in WallpaperManager::InitializeWallpaper().
1300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbase::FilePath GetCustomizedWallpaperDefaultRescaledFileName(
1310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const std::string& suffix) {
1320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const base::FilePath default_downloaded_file_name =
1330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      ServicesCustomizationDocument::GetCustomizedWallpaperDownloadedFileName();
1340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const base::FilePath default_cache_dir =
1350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      ServicesCustomizationDocument::GetCustomizedWallpaperCacheDir();
1360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (default_downloaded_file_name.empty() || default_cache_dir.empty())
1370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return base::FilePath();
1380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return default_cache_dir.Append(
1390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      default_downloaded_file_name.BaseName().value() + suffix);
1400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Whether DesktopBackgroundController should start with customized default
1430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// wallpaper in WallpaperManager::InitializeWallpaper() or not.
1440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool ShouldUseCustomizedDefaultWallpaper() {
1450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  PrefService* pref_service = g_browser_process->local_state();
1460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return !(pref_service->FindPreference(
1480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                             prefs::kCustomizationDefaultWallpaperURL)
1490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch               ->IsDefaultValue());
1500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Deletes a list of wallpaper files in |file_list|.
1535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid DeleteWallpaperInList(const std::vector<base::FilePath>& file_list) {
1545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  for (std::vector<base::FilePath>::const_iterator it = file_list.begin();
1555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu       it != file_list.end(); ++it) {
1565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    base::FilePath path = *it;
1575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Some users may still have legacy wallpapers with png extension. We need
1585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // to delete these wallpapers too.
1595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (!base::DeleteFile(path, true) &&
1605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        !base::DeleteFile(path.AddExtension(".png"), false)) {
1615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      LOG(ERROR) << "Failed to remove user wallpaper at " << path.value();
1625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
1635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Creates all new custom wallpaper directories for |user_id_hash| if not exist.
1676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// static
1685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid EnsureCustomWallpaperDirectories(const std::string& user_id_hash) {
1695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  base::FilePath dir;
1705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  dir = GetCustomWallpaperDir(kSmallWallpaperSubDir);
1715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  dir = dir.Append(user_id_hash);
1725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!base::PathExists(dir))
1735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    base::CreateDirectory(dir);
1745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  dir = GetCustomWallpaperDir(kLargeWallpaperSubDir);
1755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  dir = dir.Append(user_id_hash);
1765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!base::PathExists(dir))
1775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    base::CreateDirectory(dir);
1785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  dir = GetCustomWallpaperDir(kOriginalWallpaperSubDir);
1795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  dir = dir.Append(user_id_hash);
1805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!base::PathExists(dir))
1815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    base::CreateDirectory(dir);
1825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  dir = GetCustomWallpaperDir(kThumbnailWallpaperSubDir);
1835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  dir = dir.Append(user_id_hash);
1845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (!base::PathExists(dir))
1855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    base::CreateDirectory(dir);
1865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Saves wallpaper image raw |data| to |path| (absolute path) in file system.
1895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Returns true on success.
1905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool SaveWallpaperInternal(const base::FilePath& path,
1915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                           const char* data,
1925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                           int size) {
1935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int written_bytes = base::WriteFile(path, data, size);
1945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return written_bytes == size;
1955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// Returns index of the first public session user found in |users|
1985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// or -1 otherwise.
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int FindPublicSession(const user_manager::UserList& users) {
2005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int index = -1;
2015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int i = 0;
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (user_manager::UserList::const_iterator it = users.begin();
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       it != users.end();
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       ++it, ++i) {
205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if ((*it)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT) {
2065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      index = i;
2075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      break;
2085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
2095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
2105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return index;
2125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
2135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kWallpaperSequenceTokenName[] = "wallpaper-sequence";
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSmallWallpaperSuffix[] = "_small";
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kLargeWallpaperSuffix[] = "_large";
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kSmallWallpaperSubDir[] = "small";
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kLargeWallpaperSubDir[] = "large";
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kOriginalWallpaperSubDir[] = "original";
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kThumbnailWallpaperSubDir[] = "thumb";
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
226c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst int kSmallWallpaperMaxWidth = 1366;
227c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst int kSmallWallpaperMaxHeight = 800;
228c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst int kLargeWallpaperMaxWidth = 2560;
229c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst int kLargeWallpaperMaxHeight = 1700;
230c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst int kWallpaperThumbnailWidth = 108;
231c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst int kWallpaperThumbnailHeight = 68;
232c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static WallpaperManager* g_wallpaper_manager = NULL;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochclass WallpaperManager::CustomizedWallpaperRescaledFiles {
2360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch public:
2370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  CustomizedWallpaperRescaledFiles(const base::FilePath& path_downloaded,
2380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                   const base::FilePath& path_rescaled_small,
2390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                   const base::FilePath& path_rescaled_large);
2400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  bool AllSizesExist() const;
2420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Closure will hold unretained pointer to this object. So caller must
2440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // make sure that the closure will be destoyed before this object.
2450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Closure must be called on BlockingPool.
2460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::Closure CreateCheckerClosure();
2470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const base::FilePath& path_downloaded() const { return path_downloaded_; }
2490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const base::FilePath& path_rescaled_small() const {
2500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return path_rescaled_small_;
2510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const base::FilePath& path_rescaled_large() const {
2530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return path_rescaled_large_;
2540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const bool downloaded_exists() const { return downloaded_exists_; }
2570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const bool rescaled_small_exists() const { return rescaled_small_exists_; }
2580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const bool rescaled_large_exists() const { return rescaled_large_exists_; }
2590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch private:
2610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Must be called on BlockingPool.
2620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void CheckCustomizedWallpaperFilesExist();
2630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const base::FilePath path_downloaded_;
2650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const base::FilePath path_rescaled_small_;
2660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const base::FilePath path_rescaled_large_;
2670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  bool downloaded_exists_;
2690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  bool rescaled_small_exists_;
2700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  bool rescaled_large_exists_;
2710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(CustomizedWallpaperRescaledFiles);
2730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch};
2740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2750529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochWallpaperManager::CustomizedWallpaperRescaledFiles::
2760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    CustomizedWallpaperRescaledFiles(const base::FilePath& path_downloaded,
2770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                     const base::FilePath& path_rescaled_small,
2780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                     const base::FilePath& path_rescaled_large)
2790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    : path_downloaded_(path_downloaded),
2800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      path_rescaled_small_(path_rescaled_small),
2810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      path_rescaled_large_(path_rescaled_large),
2820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      downloaded_exists_(false),
2830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      rescaled_small_exists_(false),
2840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      rescaled_large_exists_(false) {
2850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
2860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbase::Closure
2880529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochWallpaperManager::CustomizedWallpaperRescaledFiles::CreateCheckerClosure() {
2890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return base::Bind(&WallpaperManager::CustomizedWallpaperRescaledFiles::
2900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                        CheckCustomizedWallpaperFilesExist,
2910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                    base::Unretained(this));
2920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
2930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid WallpaperManager::CustomizedWallpaperRescaledFiles::
2950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    CheckCustomizedWallpaperFilesExist() {
2960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
2970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  downloaded_exists_ = base::PathExists(path_downloaded_);
2980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rescaled_small_exists_ = base::PathExists(path_rescaled_small_);
2990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  rescaled_large_exists_ = base::PathExists(path_rescaled_large_);
3000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
3010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool WallpaperManager::CustomizedWallpaperRescaledFiles::AllSizesExist() const {
3030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return rescaled_small_exists_ && rescaled_large_exists_;
3040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
3050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This object is passed between several threads while wallpaper is being
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// loaded. It will notify callback when last reference to it is removed
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// (thus indicating that the last load action has finished).
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MovableOnDestroyCallback {
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  explicit MovableOnDestroyCallback(const base::Closure& callback)
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : callback_(callback) {
3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ~MovableOnDestroyCallback() {
3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!callback_.is_null())
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      callback_.Run();
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::Closure callback_;
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)WallpaperManager::PendingWallpaper::PendingWallpaper(
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::TimeDelta delay,
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& user_id)
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : user_id_(user_id),
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      default_(false),
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      on_finish_(new MovableOnDestroyCallback(
3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          base::Bind(&WallpaperManager::PendingWallpaper::OnWallpaperSet,
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     this))) {
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  timer.Start(
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      FROM_HERE,
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      delay,
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&WallpaperManager::PendingWallpaper::ProcessRequest, this));
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)WallpaperManager::PendingWallpaper::~PendingWallpaper() {}
3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::PendingWallpaper::ResetSetWallpaperImage(
3415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const gfx::ImageSkia& image,
3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const WallpaperInfo& info) {
3435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  SetMode(image, info, base::FilePath(), false);
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::PendingWallpaper::ResetLoadWallpaper(
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const WallpaperInfo& info) {
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetMode(gfx::ImageSkia(), info, base::FilePath(), false);
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::PendingWallpaper::ResetSetCustomWallpaper(
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const WallpaperInfo& info,
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::FilePath& wallpaper_path) {
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetMode(gfx::ImageSkia(), info, wallpaper_path, false);
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::PendingWallpaper::ResetSetDefaultWallpaper() {
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetMode(gfx::ImageSkia(), WallpaperInfo(), base::FilePath(), true);
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::PendingWallpaper::SetMode(
3625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const gfx::ImageSkia& image,
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const WallpaperInfo& info,
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::FilePath& wallpaper_path,
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const bool is_default) {
3665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  user_wallpaper_ = image;
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  info_ = info;
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  wallpaper_path_ = wallpaper_path;
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  default_ = is_default;
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::PendingWallpaper::ProcessRequest() {
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  timer.Stop();  // Erase reference to self.
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WallpaperManager* manager = WallpaperManager::Get();
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (manager->pending_inactive_ == this)
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    manager->pending_inactive_ = NULL;
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  started_load_at_ = base::Time::Now();
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (default_) {
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    manager->DoSetDefaultWallpaper(user_id_, on_finish_.Pass());
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else if (!user_wallpaper_.isNull()) {
386c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    ash::Shell::GetInstance()
387c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        ->desktop_background_controller()
388c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        ->SetWallpaperImage(user_wallpaper_, info_.layout);
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else if (!wallpaper_path_.empty()) {
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    manager->task_runner_->PostTask(
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        FROM_HERE,
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::Bind(&WallpaperManager::GetCustomWallpaperInternal,
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   user_id_,
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   info_,
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   wallpaper_path_,
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   true /* update wallpaper */,
3976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                   base::Passed(on_finish_.Pass()),
3986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                   manager->weak_factory_.GetWeakPtr()));
3995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else if (!info_.location.empty()) {
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    manager->LoadWallpaper(user_id_, info_, true, on_finish_.Pass());
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // PendingWallpaper was created and never initialized?
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NOTREACHED();
4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Error. Do not record time.
4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    started_load_at_ = base::Time();
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  on_finish_.reset();
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::PendingWallpaper::OnWallpaperSet() {
4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The only known case for this check to fail is global destruction during
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // wallpaper load. It should never happen.
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!BrowserThread::CurrentlyOn(BrowserThread::UI))
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return; // We are in a process of global destruction.
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  timer.Stop();  // Erase reference to self.
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WallpaperManager* manager = WallpaperManager::Get();
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!started_load_at_.is_null()) {
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::TimeDelta elapsed = base::Time::Now() - started_load_at_;
4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    manager->SaveLastLoadTime(elapsed);
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (manager->pending_inactive_ == this) {
4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // ProcessRequest() was never executed.
4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    manager->pending_inactive_ = NULL;
4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Destroy self.
431cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  manager->RemovePendingWallpaperFromList(this);
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WallpaperManager, public: ---------------------------------------------------
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
436a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// TestApi. For testing purpose
437a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)WallpaperManager::TestApi::TestApi(WallpaperManager* wallpaper_manager)
438a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    : wallpaper_manager_(wallpaper_manager) {
439a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
440a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
441a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)WallpaperManager::TestApi::~TestApi() {
442a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
443a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
444a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)base::FilePath WallpaperManager::TestApi::current_wallpaper_path() {
445a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return wallpaper_manager_->current_wallpaper_path_;
446a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
447a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool WallpaperManager::TestApi::GetWallpaperFromCache(
4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& user_id, gfx::ImageSkia* image) {
4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return wallpaper_manager_->GetWallpaperFromCache(user_id, image);
4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::TestApi::SetWallpaperCache(const std::string& user_id,
4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                  const gfx::ImageSkia& image) {
4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!image.isNull());
4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  wallpaper_manager_->wallpaper_cache_[user_id] = image;
4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
459a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WallpaperManager::TestApi::ClearDisposableWallpaperCache() {
460a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  wallpaper_manager_->ClearDisposableWallpaperCache();
4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WallpaperManager* WallpaperManager::Get() {
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!g_wallpaper_manager)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_wallpaper_manager = new WallpaperManager();
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return g_wallpaper_manager;
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WallpaperManager::WallpaperManager()
47168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    : loaded_wallpapers_(0),
472a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      command_line_for_testing_(NULL),
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      should_cache_wallpaper_(false),
4741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      pending_inactive_(NULL),
4751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      weak_factory_(this) {
476c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SetDefaultWallpaperPathsFromCommandLine(
477c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      base::CommandLine::ForCurrentProcess());
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this,
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 chrome::NOTIFICATION_LOGIN_USER_CHANGED,
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::NotificationService::AllSources());
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this,
482a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::NotificationService::AllSources());
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this,
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 chrome::NOTIFICATION_WALLPAPER_ANIMATION_FINISHED,
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::NotificationService::AllSources());
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sequence_token_ = BrowserThread::GetBlockingPool()->
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetNamedSequenceToken(kWallpaperSequenceTokenName);
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  task_runner_ = BrowserThread::GetBlockingPool()->
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GetSequencedTaskRunnerWithShutdownBehavior(
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          sequence_token_,
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  wallpaper_loader_ = new UserImageLoader(ImageDecoder::ROBUST_JPEG_CODEC,
494f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                          task_runner_);
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)WallpaperManager::~WallpaperManager() {
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(bshe): Lifetime of WallpaperManager needs more consideration.
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // http://crbug.com/171694
50068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(!show_user_name_on_signin_subscription_);
5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ClearObsoleteWallpaperPrefs();
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  weak_factory_.InvalidateWeakPtrs();
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WallpaperManager::Shutdown() {
50768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  show_user_name_on_signin_subscription_.reset();
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WallpaperManager::RegisterPrefs(PrefRegistrySimple* registry) {
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registry->RegisterDictionaryPref(prefs::kUsersWallpaperInfo);
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registry->RegisterDictionaryPref(kUserWallpapers);
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  registry->RegisterDictionaryPref(kUserWallpapersProperties);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WallpaperManager::AddObservers() {
51868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  show_user_name_on_signin_subscription_ =
51968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      CrosSettings::Get()->AddSettingsObserver(
52068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          kAccountsPrefShowUserNamesOnSignIn,
52168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          base::Bind(&WallpaperManager::InitializeRegisteredDeviceWallpaper,
5226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                     weak_factory_.GetWeakPtr()));
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WallpaperManager::EnsureLoggedInUserWallpaperLoaded() {
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Some browser tests do not have a shell instance. As no wallpaper is needed
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // in these tests anyway, avoid loading one, preventing crashes and speeding
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // up the tests.
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!ash::Shell::HasInstance())
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WallpaperInfo info;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GetLoggedInUserWallpaperInfo(&info)) {
5346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Ash.Wallpaper.Type", info.type,
5356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                              user_manager::User::WALLPAPER_TYPE_COUNT);
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (info == current_user_wallpaper_info_)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  SetUserWallpaperNow(
5406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user_manager::UserManager::Get()->GetLoggedInUser()->email());
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
543a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WallpaperManager::ClearDisposableWallpaperCache() {
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cancel callback for previous cache requests.
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  weak_factory_.InvalidateWeakPtrs();
546cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Keep the wallpaper of logged in users in cache at multi-profile mode.
547cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::set<std::string> logged_in_users_names;
5485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const user_manager::UserList& logged_users =
5496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user_manager::UserManager::Get()->GetLoggedInUsers();
5505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  for (user_manager::UserList::const_iterator it = logged_users.begin();
551cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       it != logged_users.end();
552cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       ++it) {
553cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    logged_in_users_names.insert((*it)->email());
554cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
556cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CustomWallpaperMap logged_in_users_cache;
557cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (CustomWallpaperMap::iterator it = wallpaper_cache_.begin();
558cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       it != wallpaper_cache_.end(); ++it) {
559cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (logged_in_users_names.find(it->first) !=
560cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        logged_in_users_names.end()) {
561cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      logged_in_users_cache.insert(*it);
5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
5635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
564cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  wallpaper_cache_ = logged_in_users_cache;
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WallpaperManager::GetLoggedInUserWallpaperInfo(WallpaperInfo* info) {
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (user_manager::UserManager::Get()->IsLoggedInAsStub()) {
5715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    info->location = current_user_wallpaper_info_.location = "";
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    info->layout = current_user_wallpaper_info_.layout =
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ash::WALLPAPER_LAYOUT_CENTER_CROPPED;
5745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    info->type = current_user_wallpaper_info_.type =
5755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        user_manager::User::DEFAULT;
5765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    info->date = current_user_wallpaper_info_.date =
5775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        base::Time::Now().LocalMidnight();
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return GetUserWallpaperInfo(
5826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user_manager::UserManager::Get()->GetLoggedInUser()->email(), info);
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WallpaperManager::InitializeWallpaper() {
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
5876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  user_manager::UserManager* user_manager = user_manager::UserManager::Get();
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Apply device customization.
5900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (ShouldUseCustomizedDefaultWallpaper()) {
5910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    SetDefaultWallpaperPath(
5920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        GetCustomizedWallpaperDefaultRescaledFileName(kSmallWallpaperSuffix),
5930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        scoped_ptr<gfx::ImageSkia>().Pass(),
5940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        GetCustomizedWallpaperDefaultRescaledFileName(kLargeWallpaperSuffix),
5950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        scoped_ptr<gfx::ImageSkia>().Pass());
5960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
5970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
598c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  CommandLine* command_line = GetCommandLine();
599a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (command_line->HasSwitch(chromeos::switches::kGuestSession)) {
600a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // Guest wallpaper should be initialized when guest login.
601a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // Note: This maybe called before login. So IsLoggedInAsGuest can not be
602a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // used here to determine if current user is guest.
603a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return;
604a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
605a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
606a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (command_line->HasSwitch(::switches::kTestType))
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WizardController::SetZeroDelays();
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Zero delays is also set in autotests.
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (WizardController::IsZeroDelayEnabled()) {
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Ensure tests have some sort of wallpaper.
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ash::Shell::GetInstance()->desktop_background_controller()->
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        CreateEmptyWallpaper();
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!user_manager->IsUserLoggedIn()) {
618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!StartupUtils::IsDeviceRegistered())
619116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      SetDefaultWallpaperDelayed(chromeos::login::kSignInUser);
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      InitializeRegisteredDeviceWallpaper();
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetUserWallpaperDelayed(user_manager->GetLoggedInUser()->email());
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WallpaperManager::Observe(int type,
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const content::NotificationSource& source,
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const content::NotificationDetails& details) {
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chrome::NOTIFICATION_LOGIN_USER_CHANGED: {
633a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ClearDisposableWallpaperCache();
6344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      BrowserThread::PostDelayedTask(
6354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          BrowserThread::UI,
6364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          FROM_HERE,
6374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          base::Bind(&WallpaperManager::MoveLoggedInUserCustomWallpaper,
6384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                     weak_factory_.GetWeakPtr()),
6394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          base::TimeDelta::FromSeconds(kMoveCustomWallpaperDelaySeconds));
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
642a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    case chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE: {
643c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      if (!GetCommandLine()->HasSwitch(switches::kDisableBootAnimation)) {
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BrowserThread::PostDelayedTask(
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            BrowserThread::UI, FROM_HERE,
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            base::Bind(&WallpaperManager::CacheUsersWallpapers,
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       weak_factory_.GetWeakPtr()),
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            base::TimeDelta::FromMilliseconds(kCacheWallpaperDelayMs));
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      } else {
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        should_cache_wallpaper_ = true;
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case chrome::NOTIFICATION_WALLPAPER_ANIMATION_FINISHED: {
655f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      NotifyAnimationFinished();
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (should_cache_wallpaper_) {
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BrowserThread::PostDelayedTask(
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            BrowserThread::UI, FROM_HERE,
6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            base::Bind(&WallpaperManager::CacheUsersWallpapers,
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       weak_factory_.GetWeakPtr()),
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            base::TimeDelta::FromMilliseconds(kCacheWallpaperDelayMs));
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        should_cache_wallpaper_ = false;
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED() << "Unexpected notification " << type;
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::RemoveUserWallpaperInfo(const std::string& user_id) {
6724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  WallpaperInfo info;
6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GetUserWallpaperInfo(user_id, &info);
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefService* prefs = g_browser_process->local_state();
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryPrefUpdate prefs_wallpapers_info_update(prefs,
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs::kUsersWallpaperInfo);
6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  prefs_wallpapers_info_update->RemoveWithoutPathExpansion(user_id, NULL);
6785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DeleteUserWallpapers(user_id, info.location);
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// static
6825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool WallpaperManager::ResizeImage(const gfx::ImageSkia& image,
6835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                   ash::WallpaperLayout layout,
6845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                   int preferred_width,
6855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                   int preferred_height,
6865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                   scoped_refptr<base::RefCountedBytes>* output,
6875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                   gfx::ImageSkia* output_skia) {
6885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
6895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int width = image.width();
6905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int height = image.height();
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int resized_width;
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int resized_height;
6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *output = new base::RefCountedBytes();
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (layout == ash::WALLPAPER_LAYOUT_CENTER_CROPPED) {
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Do not resize custom wallpaper if it is smaller than preferred size.
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!(width > preferred_width && height > preferred_height))
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return false;
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double horizontal_ratio = static_cast<double>(preferred_width) / width;
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double vertical_ratio = static_cast<double>(preferred_height) / height;
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (vertical_ratio > horizontal_ratio) {
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      resized_width =
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          RoundPositive(static_cast<double>(width) * vertical_ratio);
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      resized_height = preferred_height;
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      resized_width = preferred_width;
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      resized_height =
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          RoundPositive(static_cast<double>(height) * horizontal_ratio);
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (layout == ash::WALLPAPER_LAYOUT_STRETCH) {
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resized_width = preferred_width;
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    resized_height = preferred_height;
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resized_width = width;
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    resized_height = height;
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::ImageSkia resized_image = gfx::ImageSkiaOperations::CreateResizedImage(
7205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      image,
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      skia::ImageOperations::RESIZE_LANCZOS3,
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gfx::Size(resized_width, resized_height));
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  SkBitmap bitmap = *(resized_image.bitmap());
7255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  SkAutoLockPixels lock_input(bitmap);
7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::JPEGCodec::Encode(
7275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      reinterpret_cast<unsigned char*>(bitmap.getAddr32(0, 0)),
7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      gfx::JPEGCodec::FORMAT_SkBitmap,
7295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      bitmap.width(),
7305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      bitmap.height(),
7315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      bitmap.width() * bitmap.bytesPerPixel(),
7325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      kDefaultEncodingQuality,
7335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      &(*output)->data());
734c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
735c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (output_skia) {
736c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    resized_image.MakeThreadSafe();
737c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    *output_skia = resized_image;
738c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
739c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
7402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
7412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
7435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// static
7445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool WallpaperManager::ResizeAndSaveWallpaper(const gfx::ImageSkia& image,
7455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                              const base::FilePath& path,
7465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                              ash::WallpaperLayout layout,
7475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                              int preferred_width,
7485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                              int preferred_height,
7495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                              gfx::ImageSkia* output_skia) {
7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (layout == ash::WALLPAPER_LAYOUT_CENTER) {
7512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(bshe): Generates cropped custom wallpaper for CENTER layout.
7527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (base::PathExists(path))
7537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::DeleteFile(path, false);
754c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return false;
7552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::RefCountedBytes> data;
7575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (ResizeImage(image,
7585c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                  layout,
7595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                  preferred_width,
7605c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                  preferred_height,
7615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                  &data,
7625c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                  output_skia)) {
763c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return SaveWallpaperInternal(
764c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        path, reinterpret_cast<const char*>(data->front()), data->size());
7652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
766c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return false;
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
769a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool WallpaperManager::IsPolicyControlled(const std::string& user_id) const {
770a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  chromeos::WallpaperInfo info;
771a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!GetUserWallpaperInfo(user_id, &info))
772a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
7735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return info.type == user_manager::User::POLICY;
774a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
775a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
776a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WallpaperManager::OnPolicySet(const std::string& policy,
777a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                   const std::string& user_id) {
778a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  WallpaperInfo info;
779a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GetUserWallpaperInfo(user_id, &info);
7805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  info.type = user_manager::User::POLICY;
781a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SetUserWallpaperInfo(user_id, info, true /* is_persistent */);
782a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
783a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
784a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WallpaperManager::OnPolicyCleared(const std::string& policy,
785a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                       const std::string& user_id) {
786a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  WallpaperInfo info;
787a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GetUserWallpaperInfo(user_id, &info);
7885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  info.type = user_manager::User::DEFAULT;
789a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SetUserWallpaperInfo(user_id, info, true /* is_persistent */);
790a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SetDefaultWallpaperNow(user_id);
791a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
792a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
793a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WallpaperManager::OnPolicyFetched(const std::string& policy,
794a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                       const std::string& user_id,
795a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                       scoped_ptr<std::string> data) {
796a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!data)
797a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
798a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
799a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  wallpaper_loader_->Start(
800a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      data.Pass(),
801a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      0,  // Do not crop.
802a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::Bind(&WallpaperManager::SetPolicyControlledWallpaper,
803a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 weak_factory_.GetWeakPtr(),
804a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                 user_id));
805a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
806a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
807c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// static
808c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochWallpaperManager::WallpaperResolution
809c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochWallpaperManager::GetAppropriateResolution() {
810c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
811c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  gfx::Size size =
812c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      ash::DesktopBackgroundController::GetMaxDisplaySizeInNative();
813c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return (size.width() > kSmallWallpaperMaxWidth ||
814c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          size.height() > kSmallWallpaperMaxHeight)
815c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch             ? WALLPAPER_RESOLUTION_LARGE
816c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch             : WALLPAPER_RESOLUTION_SMALL;
817c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
818c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
8196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// static
8206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)base::FilePath WallpaperManager::GetCustomWallpaperPath(
8216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const char* sub_dir,
8226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const std::string& user_id_hash,
8236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const std::string& file) {
8246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  base::FilePath custom_wallpaper_path = GetCustomWallpaperDir(sub_dir);
8256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  return custom_wallpaper_path.Append(user_id_hash).Append(file);
8266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
8276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
828a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WallpaperManager::SetPolicyControlledWallpaper(
829a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& user_id,
830116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const user_manager::UserImage& user_image) {
8315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const user_manager::User* user =
8326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user_manager::UserManager::Get()->FindUser(user_id);
833a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!user) {
834a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    NOTREACHED() << "Unknown user.";
835a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
836a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
8375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (user->username_hash().empty()) {
8395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    cryptohome::AsyncMethodCaller::GetInstance()->AsyncGetSanitizedUsername(
8405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        user_id,
8415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::Bind(&WallpaperManager::SetCustomWallpaperOnSanitizedUsername,
8425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   weak_factory_.GetWeakPtr(),
8435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   user_id,
8445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   user_image.image(),
8455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   true /* update wallpaper */));
8465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else {
8475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    SetCustomWallpaper(user_id,
8485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       user->username_hash(),
8495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       "policy-controlled.jpeg",
8505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       ash::WALLPAPER_LAYOUT_CENTER_CROPPED,
8515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       user_manager::User::POLICY,
8525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       user_image.image(),
8535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       true /* update wallpaper */);
8545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
8555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
8565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void WallpaperManager::SetCustomWallpaperOnSanitizedUsername(
8585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& user_id,
8595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const gfx::ImageSkia& image,
8605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool update_wallpaper,
8615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool cryptohome_success,
8625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& user_id_hash) {
8635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!cryptohome_success)
8645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return;
865a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SetCustomWallpaper(user_id,
8665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                     user_id_hash,
867a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     "policy-controlled.jpeg",
868a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                     ash::WALLPAPER_LAYOUT_CENTER_CROPPED,
8695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                     user_manager::User::POLICY,
8705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                     image,
8715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                     update_wallpaper);
8725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
8735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
8745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void WallpaperManager::SetCustomWallpaper(
8755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& user_id,
8765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& user_id_hash,
8775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const std::string& file,
8785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ash::WallpaperLayout layout,
8795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    user_manager::User::WallpaperType type,
8805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    const gfx::ImageSkia& image,
8815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    bool update_wallpaper) {
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
8835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
884a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // There is no visible background in kiosk mode.
8856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (user_manager::UserManager::Get()->IsLoggedInAsKioskApp())
8865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
888a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Don't allow custom wallpapers while policy is in effect.
8895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (type != user_manager::User::POLICY && IsPolicyControlled(user_id))
890a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return;
891a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
8924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::FilePath wallpaper_path =
8934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      GetCustomWallpaperPath(kOriginalWallpaperSubDir, user_id_hash, file);
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // If decoded wallpaper is empty, we have probably failed to decode the file.
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use default wallpaper in this case.
8975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (image.isNull()) {
8985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SetDefaultWallpaperDelayed(user_id);
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const user_manager::User* user =
9036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user_manager::UserManager::Get()->FindUser(user_id);
9045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  CHECK(user);
9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_persistent =
9066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      !user_manager::UserManager::Get()->IsUserNonCryptohomeDataEphemeral(
9076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          user_id) ||
9085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      (type == user_manager::User::POLICY &&
9095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)       user->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT);
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WallpaperInfo wallpaper_info = {
9122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      wallpaper_path.value(),
9132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layout,
9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      type,
9152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Date field is not used.
9162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Time::Now().LocalMidnight()
9172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
9185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (is_persistent) {
9195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    image.EnsureRepsForSupportedScales();
9205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    scoped_ptr<gfx::ImageSkia> deep_copy(image.DeepCopy());
9215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Block shutdown on this task. Otherwise, we may lose the custom wallpaper
9225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // that the user selected.
9235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    scoped_refptr<base::SequencedTaskRunner> blocking_task_runner =
9245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        BrowserThread::GetBlockingPool()
9255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu            ->GetSequencedTaskRunnerWithShutdownBehavior(
9265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                sequence_token_, base::SequencedWorkerPool::BLOCK_SHUTDOWN);
9275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // TODO(bshe): This may break if RawImage becomes RefCountedMemory.
9285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    blocking_task_runner->PostTask(
9295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        FROM_HERE,
9305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        base::Bind(&WallpaperManager::SaveCustomWallpaper,
9315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   user_id_hash,
9325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   base::FilePath(wallpaper_info.location),
9335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   wallpaper_info.layout,
9345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                   base::Passed(deep_copy.Pass())));
9355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string relative_path = base::FilePath(user_id_hash).Append(file).value();
9384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // User's custom wallpaper path is determined by relative path and the
9392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // appropriate wallpaper resolution in GetCustomWallpaperInternal.
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WallpaperInfo info = {
9414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      relative_path,
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      layout,
943a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      type,
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Time::Now().LocalMidnight()
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
9465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetUserWallpaperInfo(user_id, info, is_persistent);
9475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (update_wallpaper) {
9485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    GetPendingWallpaper(user_id, false)->ResetSetWallpaperImage(image, info);
9495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
9505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
951cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  wallpaper_cache_[user_id] = image;
9525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
9535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::SetDefaultWallpaperNow(const std::string& user_id) {
9555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GetPendingWallpaper(user_id, false)->ResetSetDefaultWallpaper();
9565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
9575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::SetDefaultWallpaperDelayed(const std::string& user_id) {
9595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GetPendingWallpaper(user_id, true)->ResetSetDefaultWallpaper();
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::DoSetDefaultWallpaper(
9635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& user_id,
9645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MovableOnDestroyCallbackHolder on_finish) {
96523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // There is no visible background in kiosk mode.
9666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (user_manager::UserManager::Get()->IsLoggedInAsKioskApp())
9675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
9682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_wallpaper_path_.clear();
9695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  wallpaper_cache_.erase(user_id);
9705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Some browser tests do not have a shell instance. As no wallpaper is needed
9715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // in these tests anyway, avoid loading one, preventing crashes and speeding
9725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // up the tests.
9735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!ash::Shell::HasInstance())
9745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
975c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
976c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  WallpaperResolution resolution = GetAppropriateResolution();
977c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  const bool use_small = (resolution == WALLPAPER_RESOLUTION_SMALL);
978c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
979c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  const base::FilePath* file = NULL;
980c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
9816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (user_manager::UserManager::Get()->IsLoggedInAsGuest()) {
982c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    file =
983c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        use_small ? &guest_small_wallpaper_file_ : &guest_large_wallpaper_file_;
984c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  } else {
985c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    file = use_small ? &default_small_wallpaper_file_
986c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                     : &default_large_wallpaper_file_;
987c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
988cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ash::WallpaperLayout layout = use_small
989cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    ? ash::WALLPAPER_LAYOUT_CENTER
990cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    : ash::WALLPAPER_LAYOUT_CENTER_CROPPED;
991c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  DCHECK(file);
992c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!default_wallpaper_image_.get() ||
9930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      default_wallpaper_image_->file_path() != file->value()) {
994c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    default_wallpaper_image_.reset();
995c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (!file->empty()) {
996c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      loaded_wallpapers_++;
997c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      StartLoadAndSetDefaultWallpaper(
998c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          *file, layout, on_finish.Pass(), &default_wallpaper_image_);
999c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      return;
1000c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    }
1001c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1002cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    CreateSolidDefaultWallpaper();
1003c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
1004cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // 1x1 wallpaper is actually solid color, so it should be stretched.
1005cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (default_wallpaper_image_->image().width() == 1 &&
1006cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      default_wallpaper_image_->image().height() == 1)
1007cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    layout = ash::WALLPAPER_LAYOUT_STRETCH;
1008cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1009c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ash::Shell::GetInstance()->desktop_background_controller()->SetWallpaperImage(
1010c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      default_wallpaper_image_->image(), layout);
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// static
10146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void WallpaperManager::SaveCustomWallpaper(const std::string& user_id_hash,
10156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                           const base::FilePath& original_path,
10166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                           ash::WallpaperLayout layout,
10176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                           scoped_ptr<gfx::ImageSkia> image) {
10185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::DeleteFile(
10195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      GetCustomWallpaperDir(kOriginalWallpaperSubDir).Append(user_id_hash),
10205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      true /* recursive */);
10215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::DeleteFile(
10225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      GetCustomWallpaperDir(kSmallWallpaperSubDir).Append(user_id_hash),
10235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      true /* recursive */);
10245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::DeleteFile(
10255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      GetCustomWallpaperDir(kLargeWallpaperSubDir).Append(user_id_hash),
10265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      true /* recursive */);
10276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  EnsureCustomWallpaperDirectories(user_id_hash);
10286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  std::string file_name = original_path.BaseName().value();
10296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  base::FilePath small_wallpaper_path =
10306d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      GetCustomWallpaperPath(kSmallWallpaperSubDir, user_id_hash, file_name);
10316d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  base::FilePath large_wallpaper_path =
10326d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      GetCustomWallpaperPath(kLargeWallpaperSubDir, user_id_hash, file_name);
10336d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
10346d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // Re-encode orginal file to jpeg format and saves the result in case that
10356d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // resized wallpaper is not generated (i.e. chrome shutdown before resized
10366d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  // wallpaper is saved).
10376d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ResizeAndSaveWallpaper(*image,
10386d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                         original_path,
10396d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                         ash::WALLPAPER_LAYOUT_STRETCH,
10406d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                         image->width(),
10416d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                         image->height(),
10426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                         NULL);
10436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ResizeAndSaveWallpaper(*image,
10446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                         small_wallpaper_path,
10456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                         layout,
10466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                         kSmallWallpaperMaxWidth,
10476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                         kSmallWallpaperMaxHeight,
10486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                         NULL);
10496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  ResizeAndSaveWallpaper(*image,
10506d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                         large_wallpaper_path,
10516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                         layout,
10526d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                         kLargeWallpaperMaxWidth,
10536d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                         kLargeWallpaperMaxHeight,
10546d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                         NULL);
10556d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
10566d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
10576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// static
10586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void WallpaperManager::MoveCustomWallpapersOnWorker(
10596d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const std::string& user_id,
10606d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const std::string& user_id_hash,
10616d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    base::WeakPtr<WallpaperManager> weak_ptr) {
10626d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
10636d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (MoveCustomWallpaperDirectory(
10646d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)          kOriginalWallpaperSubDir, user_id, user_id_hash)) {
10656d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // Consider success if the original wallpaper is moved to the new directory.
10666d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // Original wallpaper is the fallback if the correct resolution wallpaper
10676d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // can not be found.
10686d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    BrowserThread::PostTask(
10696d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        BrowserThread::UI,
10706d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        FROM_HERE,
10716d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)        base::Bind(&WallpaperManager::MoveCustomWallpapersSuccess,
10726d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                   weak_ptr,
10736d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                   user_id,
10746d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                   user_id_hash));
10756d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
10766d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  MoveCustomWallpaperDirectory(kLargeWallpaperSubDir, user_id, user_id_hash);
10776d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  MoveCustomWallpaperDirectory(kSmallWallpaperSubDir, user_id, user_id_hash);
10786d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  MoveCustomWallpaperDirectory(
10796d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)      kThumbnailWallpaperSubDir, user_id, user_id_hash);
10806d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
10816d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
10826d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)// static
10836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void WallpaperManager::GetCustomWallpaperInternal(
10846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const std::string& user_id,
10856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const WallpaperInfo& info,
10866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    const base::FilePath& wallpaper_path,
10876d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    bool update_wallpaper,
10886d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    MovableOnDestroyCallbackHolder on_finish,
10896d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    base::WeakPtr<WallpaperManager> weak_ptr) {
10906d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
10916d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  base::FilePath valid_path = wallpaper_path;
10926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (!base::PathExists(wallpaper_path)) {
10936d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // Falls back on original file if the correct resolution file does not
10946d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // exist. This may happen when the original custom wallpaper is small or
10956d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // browser shutdown before resized wallpaper saved.
10966d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    valid_path = GetCustomWallpaperDir(kOriginalWallpaperSubDir);
10975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    valid_path = valid_path.Append(info.location);
10986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
10996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
11006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (!base::PathExists(valid_path)) {
11016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // Falls back to custom wallpaper that uses email as part of its file path.
11026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    // Note that email is used instead of user_id_hash here.
11035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    valid_path = GetCustomWallpaperPath(kOriginalWallpaperSubDir,
11045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                        user_id, info.location);
11056d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
11066d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
11076d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  if (!base::PathExists(valid_path)) {
11086d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    LOG(ERROR) << "Failed to load previously selected custom wallpaper. " <<
11096d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                  "Fallback to default wallpaper";
11106d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    BrowserThread::PostTask(BrowserThread::UI,
11116d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                            FROM_HERE,
11126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                            base::Bind(&WallpaperManager::DoSetDefaultWallpaper,
11136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                       weak_ptr,
11146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                       user_id,
11156d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                       base::Passed(on_finish.Pass())));
11166d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  } else {
11176d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)    BrowserThread::PostTask(BrowserThread::UI,
11186d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                            FROM_HERE,
11196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                            base::Bind(&WallpaperManager::StartLoad,
11206d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                       weak_ptr,
11216d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                       user_id,
11226d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                       info,
11236d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                       update_wallpaper,
11246d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                       valid_path,
11256d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                       base::Passed(on_finish.Pass())));
11266d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)  }
11276d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}
11286d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
11295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::InitInitialUserWallpaper(const std::string& user_id,
11305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                bool is_persistent) {
11315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  current_user_wallpaper_info_.location = "";
11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_user_wallpaper_info_.layout = ash::WALLPAPER_LAYOUT_CENTER_CROPPED;
11335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  current_user_wallpaper_info_.type = user_manager::User::DEFAULT;
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  current_user_wallpaper_info_.date = base::Time::Now().LocalMidnight();
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WallpaperInfo info = current_user_wallpaper_info_;
11375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetUserWallpaperInfo(user_id, info, is_persistent);
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::SetUserWallpaperInfo(const std::string& user_id,
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            const WallpaperInfo& info,
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            bool is_persistent) {
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  current_user_wallpaper_info_ = info;
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!is_persistent)
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrefService* local_state = g_browser_process->local_state();
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryPrefUpdate wallpaper_update(local_state,
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        prefs::kUsersWallpaperInfo);
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::DictionaryValue* wallpaper_info_dict = new base::DictionaryValue();
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wallpaper_info_dict->SetString(kNewWallpaperDateNodeName,
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Int64ToString(info.date.ToInternalValue()));
11555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  wallpaper_info_dict->SetString(kNewWallpaperLocationNodeName, info.location);
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wallpaper_info_dict->SetInteger(kNewWallpaperLayoutNodeName, info.layout);
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wallpaper_info_dict->SetInteger(kNewWallpaperTypeNodeName, info.type);
11585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  wallpaper_update->SetWithoutPathExpansion(user_id, wallpaper_info_dict);
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::SetUserWallpaperDelayed(const std::string& user_id) {
11625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScheduleSetUserWallpaper(user_id, true);
11635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
11645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
11655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::SetUserWallpaperNow(const std::string& user_id) {
11665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ScheduleSetUserWallpaper(user_id, false);
11675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
11685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
11695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::ScheduleSetUserWallpaper(const std::string& user_id,
11705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                bool delayed) {
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
11725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Some unit tests come here without a UserManager or without a pref system.
11736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!user_manager::UserManager::IsInitialized() ||
11746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      !g_browser_process->local_state()) {
11755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
11766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
11776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
11785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // There is no visible background in kiosk mode.
11796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (user_manager::UserManager::Get()->IsLoggedInAsKioskApp())
11805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
11815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Guest user, regular user in ephemeral mode, or kiosk app.
11826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const user_manager::User* user =
11836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user_manager::UserManager::Get()->FindUser(user_id);
11846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (user_manager::UserManager::Get()->IsUserNonCryptohomeDataEphemeral(
11856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          user_id) ||
1186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      (user != NULL && user->GetType() == user_manager::USER_TYPE_KIOSK_APP)) {
11875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    InitInitialUserWallpaper(user_id, false);
11885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GetPendingWallpaper(user_id, delayed)->ResetSetDefaultWallpaper();
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (!user_manager::UserManager::Get()->IsKnownUser(user_id))
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  last_selected_user_ = user_id;
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WallpaperInfo info;
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!GetUserWallpaperInfo(user_id, &info)) {
12005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    InitInitialUserWallpaper(user_id, true);
12015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GetUserWallpaperInfo(user_id, &info);
12025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::ImageSkia user_wallpaper;
12055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  current_user_wallpaper_info_ = info;
12065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (GetWallpaperFromCache(user_id, &user_wallpaper)) {
12075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GetPendingWallpaper(user_id, delayed)
12085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ->ResetSetWallpaperImage(user_wallpaper, info);
12095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
12105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (info.location.empty()) {
121146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      // Uses default built-in wallpaper when file is empty. Eventually, we
121246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      // will only ship one built-in wallpaper in ChromeOS image.
121346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      GetPendingWallpaper(user_id, delayed)->ResetSetDefaultWallpaper();
121446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      return;
121546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    }
121646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
12175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (info.type == user_manager::User::CUSTOMIZED ||
12185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.type == user_manager::User::POLICY) {
1219c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      const char* sub_dir = GetCustomWallpaperSubdirForCurrentResolution();
12205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Wallpaper is not resized when layout is ash::WALLPAPER_LAYOUT_CENTER.
12215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // Original wallpaper should be used in this case.
12225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      // TODO(bshe): Generates cropped custom wallpaper for CENTER layout.
12235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (info.layout == ash::WALLPAPER_LAYOUT_CENTER)
12245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        sub_dir = kOriginalWallpaperSubDir;
12255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::FilePath wallpaper_path = GetCustomWallpaperDir(sub_dir);
12265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      wallpaper_path = wallpaper_path.Append(info.location);
12275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      if (current_wallpaper_path_ == wallpaper_path)
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
12295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      current_wallpaper_path_ = wallpaper_path;
12305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      loaded_wallpapers_++;
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GetPendingWallpaper(user_id, delayed)
12335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          ->ResetSetCustomWallpaper(info, wallpaper_path);
12345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return;
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Load downloaded ONLINE or converted DEFAULT wallpapers.
12385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GetPendingWallpaper(user_id, delayed)->ResetLoadWallpaper(info);
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid WallpaperManager::SetWallpaperFromImageSkia(const std::string& user_id,
12435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                                 const gfx::ImageSkia& image,
12445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                                 ash::WallpaperLayout layout,
12455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                                 bool update_wallpaper) {
12466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DCHECK(user_manager::UserManager::Get()->IsUserLoggedIn());
12475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
124823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // There is no visible background in kiosk mode.
12496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (user_manager::UserManager::Get()->IsLoggedInAsKioskApp())
12505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
12515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  WallpaperInfo info;
12525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  info.layout = layout;
1253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  wallpaper_cache_[user_id] = image;
12545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
12555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (update_wallpaper) {
12565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GetPendingWallpaper(last_selected_user_, false /* Not delayed */)
12575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        ->ResetSetWallpaperImage(image, info);
12585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WallpaperManager::UpdateWallpaper(bool clear_cache) {
1262c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  FOR_EACH_OBSERVER(Observer, observers_, OnUpdateWallpaperForTesting());
1263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (clear_cache)
1264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    wallpaper_cache_.clear();
12652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  current_wallpaper_path_.clear();
1266a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // For GAIA login flow, the last_selected_user_ may not be set before user
1267a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // login. If UpdateWallpaper is called at GAIA login screen, no wallpaper will
1268a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // be set. It could result a black screen on external monitors.
1269a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // See http://crbug.com/265689 for detail.
1270a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (last_selected_user_.empty()) {
1271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SetDefaultWallpaperNow(chromeos::login::kSignInUser);
1272a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return;
1273a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
12745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetUserWallpaperNow(last_selected_user_);
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void WallpaperManager::AddObserver(WallpaperManager::Observer* observer) {
1278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  observers_.AddObserver(observer);
1279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void WallpaperManager::RemoveObserver(WallpaperManager::Observer* observer) {
1282f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  observers_.RemoveObserver(observer);
1283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void WallpaperManager::NotifyAnimationFinished() {
1286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  FOR_EACH_OBSERVER(
1287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Observer, observers_, OnWallpaperAnimationFinished(last_selected_user_));
1288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
1289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WallpaperManager, private: --------------------------------------------------
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool WallpaperManager::GetWallpaperFromCache(const std::string& user_id,
12935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                             gfx::ImageSkia* image) {
12945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
12955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CustomWallpaperMap::const_iterator it = wallpaper_cache_.find(user_id);
12965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (it != wallpaper_cache_.end()) {
12975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    *image = (*it).second;
12985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return true;
12995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
13005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return false;
13015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
13025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
13032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WallpaperManager::CacheUsersWallpapers() {
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
13056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  user_manager::UserList users = user_manager::UserManager::Get()->GetUsers();
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!users.empty()) {
13085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    user_manager::UserList::const_iterator it = users.begin();
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Skip the wallpaper of first user in the list. It should have been cached.
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    it++;
13112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int cached = 0;
13122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         it != users.end() && cached < kMaxWallpapersToCache;
13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         ++it, ++cached) {
13145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      std::string user_id = (*it)->email();
13155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      CacheUserWallpaper(user_id);
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::CacheUserWallpaper(const std::string& user_id) {
13215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (wallpaper_cache_.find(user_id) != wallpaper_cache_.end())
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WallpaperInfo info;
13245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (GetUserWallpaperInfo(user_id, &info)) {
13255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (info.location.empty())
132646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      return;
132746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
13282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath wallpaper_dir;
13292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath wallpaper_path;
13305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (info.type == user_manager::User::CUSTOMIZED ||
13315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        info.type == user_manager::User::POLICY) {
1332c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      const char* sub_dir = GetCustomWallpaperSubdirForCurrentResolution();
13334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      base::FilePath wallpaper_path = GetCustomWallpaperDir(sub_dir);
13345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      wallpaper_path = wallpaper_path.Append(info.location);
13355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      task_runner_->PostTask(
13365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          FROM_HERE,
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          base::Bind(&WallpaperManager::GetCustomWallpaperInternal,
13385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     user_id,
13395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     info,
13405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     wallpaper_path,
13415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     false /* do not update wallpaper */,
13426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                     base::Passed(MovableOnDestroyCallbackHolder()),
13436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                     weak_factory_.GetWeakPtr()));
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LoadWallpaper(user_id,
13475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  info,
13485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  false /* do not update wallpaper */,
13495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                  MovableOnDestroyCallbackHolder().Pass());
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WallpaperManager::ClearObsoleteWallpaperPrefs() {
13542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PrefService* prefs = g_browser_process->local_state();
13552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DictionaryPrefUpdate wallpaper_properties_pref(prefs,
13562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kUserWallpapersProperties);
13572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  wallpaper_properties_pref->Clear();
13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DictionaryPrefUpdate wallpapers_pref(prefs, kUserWallpapers);
13592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  wallpapers_pref->Clear();
13602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
13612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::DeleteUserWallpapers(const std::string& user_id,
13634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                            const std::string& path_to_file) {
13642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<base::FilePath> file_to_remove;
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove small user wallpaper.
1366d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  base::FilePath wallpaper_path =
13674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      GetCustomWallpaperDir(kSmallWallpaperSubDir);
13684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Remove old directory if exists
13695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  file_to_remove.push_back(wallpaper_path.Append(user_id));
13704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  wallpaper_path = wallpaper_path.Append(path_to_file).DirName();
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file_to_remove.push_back(wallpaper_path);
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove large user wallpaper.
13744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  wallpaper_path = GetCustomWallpaperDir(kLargeWallpaperSubDir);
13755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  file_to_remove.push_back(wallpaper_path.Append(user_id));
13764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  wallpaper_path = wallpaper_path.Append(path_to_file);
13772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_to_remove.push_back(wallpaper_path);
13782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
13792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Remove user wallpaper thumbnail.
13804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  wallpaper_path = GetCustomWallpaperDir(kThumbnailWallpaperSubDir);
13815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  file_to_remove.push_back(wallpaper_path.Append(user_id));
13824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  wallpaper_path = wallpaper_path.Append(path_to_file);
13832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_to_remove.push_back(wallpaper_path);
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove original user wallpaper.
13864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  wallpaper_path = GetCustomWallpaperDir(kOriginalWallpaperSubDir);
13875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  file_to_remove.push_back(wallpaper_path.Append(user_id));
13884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  wallpaper_path = wallpaper_path.Append(path_to_file);
13892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  file_to_remove.push_back(wallpaper_path);
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WorkerPool::PostTask(
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
13935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      base::Bind(&DeleteWallpaperInList, file_to_remove),
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false);
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1397c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid WallpaperManager::SetCommandLineForTesting(
1398c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    base::CommandLine* command_line) {
1399c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  command_line_for_testing_ = command_line;
1400c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  SetDefaultWallpaperPathsFromCommandLine(command_line);
1401c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
1402c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1403c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochCommandLine* WallpaperManager::GetCommandLine() {
1404a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  CommandLine* command_line = command_line_for_testing_ ?
1405a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      command_line_for_testing_ : CommandLine::ForCurrentProcess();
1406a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return command_line;
1407a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
1408a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
14092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WallpaperManager::InitializeRegisteredDeviceWallpaper() {
14106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (user_manager::UserManager::Get()->IsUserLoggedIn())
14112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
14122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1413c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  bool disable_boot_animation =
1414c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      GetCommandLine()->HasSwitch(switches::kDisableBootAnimation);
14152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool show_users = true;
14162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool result = CrosSettings::Get()->GetBoolean(
14172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kAccountsPrefShowUserNamesOnSignIn, &show_users);
14182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(result) << "Unable to fetch setting "
14192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 << kAccountsPrefShowUserNamesOnSignIn;
14206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const user_manager::UserList& users =
14216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user_manager::UserManager::Get()->GetUsers();
14225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  int public_session_user_index = FindPublicSession(users);
14235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if ((!show_users && public_session_user_index == -1) || users.empty()) {
14242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Boot into sign in form, preload default wallpaper.
1425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SetDefaultWallpaperDelayed(chromeos::login::kSignInUser);
14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
14272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!disable_boot_animation) {
14305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    int index = public_session_user_index != -1 ? public_session_user_index : 0;
14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Normal boot, load user wallpaper.
14322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If normal boot animation is disabled wallpaper would be set
14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // asynchronously once user pods are loaded.
14345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    SetUserWallpaperDelayed(users[index]->email());
14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
14385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::LoadWallpaper(const std::string& user_id,
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const WallpaperInfo& info,
14405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     bool update_wallpaper,
14415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                     MovableOnDestroyCallbackHolder on_finish) {
14422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath wallpaper_dir;
14432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath wallpaper_path;
1444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Do a sanity check that file path information is not empty.
14465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (info.type == user_manager::User::ONLINE ||
14475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      info.type == user_manager::User::DEFAULT) {
14485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (info.location.empty()) {
1449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (base::SysInfo::IsRunningOnChromeOS()) {
1450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        NOTREACHED() << "User wallpaper info appears to be broken: " << user_id;
1451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      } else {
1452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // Filename might be empty on debug configurations when stub users
1453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // were created directly in Local State (for testing). Ignore such
1454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // errors i.e. allowsuch type of debug configurations on the desktop.
1455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        LOG(WARNING) << "User wallpaper info is empty: " << user_id;
1456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // |on_finish| callback will get called on destruction.
1458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        return;
1459cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
1460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1461cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
14635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (info.type == user_manager::User::ONLINE) {
14645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    std::string file_name = GURL(info.location).ExtractFileName();
1465c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    WallpaperResolution resolution = GetAppropriateResolution();
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Only solid color wallpapers have stretch layout and they have only one
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // resolution.
14682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (info.layout != ash::WALLPAPER_LAYOUT_STRETCH &&
1469c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        resolution == WALLPAPER_RESOLUTION_SMALL) {
14702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      file_name = base::FilePath(file_name).InsertBeforeExtension(
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kSmallWallpaperSuffix).value();
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(PathService::Get(chrome::DIR_CHROMEOS_WALLPAPERS, &wallpaper_dir));
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wallpaper_path = wallpaper_dir.Append(file_name);
14752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (current_wallpaper_path_ == wallpaper_path)
14762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
14775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (update_wallpaper)
14792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      current_wallpaper_path_ = wallpaper_path;
14805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
14812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    loaded_wallpapers_++;
14825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    StartLoad(
14835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        user_id, info, update_wallpaper, wallpaper_path, on_finish.Pass());
14845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  } else if (info.type == user_manager::User::DEFAULT) {
14852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Default wallpapers are migrated from M21 user profiles. A code refactor
14862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // overlooked that case and caused these wallpapers not being loaded at all.
14872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // On some slow devices, it caused login webui not visible after upgrade to
14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // M26 from M21. See crosbug.com/38429 for details.
14892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath user_data_dir;
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
14915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    wallpaper_path = user_data_dir.Append(info.location);
14925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    StartLoad(
14935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        user_id, info, update_wallpaper, wallpaper_path, on_finish.Pass());
14942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
14952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // In unexpected cases, revert to default wallpaper to fail safely. See
14962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // crosbug.com/38429.
14972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "Wallpaper reverts to default unexpected.";
14985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    DoSetDefaultWallpaper(user_id, on_finish.Pass());
14992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
15002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
15012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
15025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool WallpaperManager::GetUserWallpaperInfo(const std::string& user_id,
1503a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                            WallpaperInfo* info) const {
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (user_manager::UserManager::Get()->IsUserNonCryptohomeDataEphemeral(
15076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          user_id)) {
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Default to the values cached in memory.
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *info = current_user_wallpaper_info_;
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Ephemeral users do not save anything to local state. But we have got
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // wallpaper info from memory. Returns true.
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1516c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  const base::DictionaryValue* info_dict;
1517c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!g_browser_process->local_state()->
1518c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          GetDictionary(prefs::kUsersWallpaperInfo)->
1519c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch              GetDictionaryWithoutPathExpansion(user_id, &info_dict)) {
1520c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return false;
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1523c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Use temporary variables to keep |info| untouched in the error case.
15245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::string location;
15255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!info_dict->GetString(kNewWallpaperLocationNodeName, &location))
1526c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return false;
1527c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  int layout;
1528c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!info_dict->GetInteger(kNewWallpaperLayoutNodeName, &layout))
1529c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return false;
1530c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  int type;
1531c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!info_dict->GetInteger(kNewWallpaperTypeNodeName, &type))
1532c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return false;
1533c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  std::string date_string;
1534c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!info_dict->GetString(kNewWallpaperDateNodeName, &date_string))
1535c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return false;
1536c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  int64 date_val;
1537c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (!base::StringToInt64(date_string, &date_val))
1538c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    return false;
1539c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
15405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  info->location = location;
1541c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  info->layout = static_cast<ash::WallpaperLayout>(layout);
15425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  info->type = static_cast<user_manager::User::WallpaperType>(type);
1543c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  info->date = base::Time::FromInternalValue(date_val);
1544c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return true;
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WallpaperManager::MoveCustomWallpapersSuccess(
15485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& user_id,
15494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string& user_id_hash) {
15504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  WallpaperInfo info;
15515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GetUserWallpaperInfo(user_id, &info);
15525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (info.type == user_manager::User::CUSTOMIZED) {
15534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // New file field should include user id hash in addition to file name.
15544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // This is needed because at login screen, user id hash is not available.
15555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    info.location = base::FilePath(user_id_hash).Append(info.location).value();
15564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    bool is_persistent =
15576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        !user_manager::UserManager::Get()->IsUserNonCryptohomeDataEphemeral(
15586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            user_id);
15595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SetUserWallpaperInfo(user_id, info, is_persistent);
15604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
15614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
15624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
15634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void WallpaperManager::MoveLoggedInUserCustomWallpaper() {
15645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const user_manager::User* logged_in_user =
15656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user_manager::UserManager::Get()->GetLoggedInUser();
15666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (logged_in_user) {
15676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    task_runner_->PostTask(
15686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        FROM_HERE,
15696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        base::Bind(&WallpaperManager::MoveCustomWallpapersOnWorker,
15706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                   logged_in_user->email(),
15716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                   logged_in_user->username_hash(),
15726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                   weak_factory_.GetWeakPtr()));
15736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::OnWallpaperDecoded(
15775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& user_id,
15785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ash::WallpaperLayout layout,
15795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool update_wallpaper,
15805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MovableOnDestroyCallbackHolder on_finish,
1581116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const user_manager::UserImage& user_image) {
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
15837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TRACE_EVENT_ASYNC_END0("ui", "LoadAndDecodeWallpaper", this);
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
158523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // If decoded wallpaper is empty, we have probably failed to decode the file.
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use default wallpaper in this case.
15875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (user_image.image().isNull()) {
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Updates user pref to default wallpaper.
15895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    WallpaperInfo info = {"", ash::WALLPAPER_LAYOUT_CENTER_CROPPED,
15905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          user_manager::User::DEFAULT,
15915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                          base::Time::Now().LocalMidnight()};
15925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SetUserWallpaperInfo(user_id, info, true);
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (update_wallpaper)
15955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      DoSetDefaultWallpaper(user_id, on_finish.Pass());
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1599cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  wallpaper_cache_[user_id] = user_image.image();
16005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (update_wallpaper) {
1602c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    ash::Shell::GetInstance()
1603c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        ->desktop_background_controller()
16045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        ->SetWallpaperImage(user_image.image(), layout);
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::StartLoad(const std::string& user_id,
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const WallpaperInfo& info,
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 bool update_wallpaper,
16115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 const base::FilePath& wallpaper_path,
16125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 MovableOnDestroyCallbackHolder on_finish) {
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
16147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  TRACE_EVENT_ASYNC_BEGIN0("ui", "LoadAndDecodeWallpaper", this);
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  wallpaper_loader_->Start(wallpaper_path.value(),
1617a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                           0,  // Do not crop.
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           base::Bind(&WallpaperManager::OnWallpaperDecoded,
16196d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)                                      weak_factory_.GetWeakPtr(),
16205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      user_id,
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      info.layout,
16225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      update_wallpaper,
16235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      base::Passed(on_finish.Pass())));
16245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
16255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WallpaperManager::SaveLastLoadTime(const base::TimeDelta elapsed) {
16275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  while (last_load_times_.size() >= kLastLoadsStatsMsMaxSize)
16285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    last_load_times_.pop_front();
16295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (elapsed > base::TimeDelta::FromMicroseconds(0)) {
16315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    last_load_times_.push_back(elapsed);
16325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    last_load_finished_at_ = base::Time::Now();
16335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
16345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
16355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::TimeDelta WallpaperManager::GetWallpaperLoadDelay() const {
16375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::TimeDelta delay;
16385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (last_load_times_.size() == 0) {
16405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    delay = base::TimeDelta::FromMilliseconds(kLoadDefaultDelayMs);
16415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
16425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    delay = std::accumulate(last_load_times_.begin(),
16435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            last_load_times_.end(),
16445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            base::TimeDelta(),
16455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            std::plus<base::TimeDelta>()) /
16465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            last_load_times_.size();
16475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
16485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (delay < base::TimeDelta::FromMilliseconds(kLoadMinDelayMs))
16505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    delay = base::TimeDelta::FromMilliseconds(kLoadMinDelayMs);
16515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  else if (delay > base::TimeDelta::FromMilliseconds(kLoadMaxDelayMs))
16525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    delay = base::TimeDelta::FromMilliseconds(kLoadMaxDelayMs);
16535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // If we had ever loaded wallpaper, adjust wait delay by time since last load.
16555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!last_load_finished_at_.is_null()) {
16565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::TimeDelta interval = base::Time::Now() - last_load_finished_at_;
16575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (interval > delay)
16585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      delay = base::TimeDelta::FromMilliseconds(0);
16595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    else if (interval > base::TimeDelta::FromMilliseconds(0))
16605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      delay -= interval;
16615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
16625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return delay;
16635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
16645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid WallpaperManager::SetCustomizedDefaultWallpaperAfterCheck(
16660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const GURL& wallpaper_url,
16670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const base::FilePath& downloaded_file,
16680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    scoped_ptr<CustomizedWallpaperRescaledFiles> rescaled_files) {
16690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  PrefService* pref_service = g_browser_process->local_state();
16700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
16710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string current_url =
16720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      pref_service->GetString(prefs::kCustomizationDefaultWallpaperURL);
16730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (current_url != wallpaper_url.spec() || !rescaled_files->AllSizesExist()) {
16740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DCHECK(rescaled_files->downloaded_exists());
16750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
16760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Either resized images do not exist or cached version is incorrect.
16770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // Need to start resize again.
16780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    wallpaper_loader_->Start(
16790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        downloaded_file.value(),
16800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        0,  // Do not crop.
16810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch        base::Bind(&WallpaperManager::OnCustomizedDefaultWallpaperDecoded,
16820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                   weak_factory_.GetWeakPtr(),
16830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                   wallpaper_url,
16840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                   base::Passed(rescaled_files.Pass())));
16850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  } else {
16860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    SetDefaultWallpaperPath(rescaled_files->path_rescaled_small(),
16870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                            scoped_ptr<gfx::ImageSkia>().Pass(),
16880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                            rescaled_files->path_rescaled_large(),
16890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                            scoped_ptr<gfx::ImageSkia>().Pass());
16900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
16910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
16920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
16930529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid WallpaperManager::OnCustomizedDefaultWallpaperDecoded(
16940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const GURL& wallpaper_url,
16950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    scoped_ptr<CustomizedWallpaperRescaledFiles> rescaled_files,
1696116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const user_manager::UserImage& wallpaper) {
16970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
16980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
16990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // If decoded wallpaper is empty, we have probably failed to decode the file.
17000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (wallpaper.image().isNull()) {
17010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    LOG(WARNING) << "Failed to decode customized wallpaper.";
17020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
17030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
17040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
17050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  wallpaper.image().EnsureRepsForSupportedScales();
17060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<gfx::ImageSkia> deep_copy(wallpaper.image().DeepCopy());
17070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
17080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<bool> success(new bool(false));
17090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<gfx::ImageSkia> small_wallpaper_image(new gfx::ImageSkia);
17100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<gfx::ImageSkia> large_wallpaper_image(new gfx::ImageSkia);
17110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
17120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // TODO(bshe): This may break if RawImage becomes RefCountedMemory.
17130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::Closure resize_closure =
17140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      base::Bind(&WallpaperManager::ResizeCustomizedDefaultWallpaper,
17150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 base::Passed(&deep_copy),
17160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 wallpaper.raw_image(),
17170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 base::Unretained(rescaled_files.get()),
17180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 base::Unretained(success.get()),
17190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 base::Unretained(small_wallpaper_image.get()),
17200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 base::Unretained(large_wallpaper_image.get()));
17210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::Closure on_resized_closure =
17220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      base::Bind(&WallpaperManager::OnCustomizedDefaultWallpaperResized,
17230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 weak_factory_.GetWeakPtr(),
17240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 wallpaper_url,
17250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 base::Passed(rescaled_files.Pass()),
17260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 base::Passed(success.Pass()),
17270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 base::Passed(small_wallpaper_image.Pass()),
17280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 base::Passed(large_wallpaper_image.Pass()));
17290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
17300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!task_runner_->PostTaskAndReply(
17310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          FROM_HERE, resize_closure, on_resized_closure)) {
17320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    LOG(WARNING) << "Failed to start Customized Wallpaper resize.";
17330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
17340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
17350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
17360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid WallpaperManager::ResizeCustomizedDefaultWallpaper(
17370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    scoped_ptr<gfx::ImageSkia> image,
1738116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const user_manager::UserImage::RawImage& raw_image,
17390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const CustomizedWallpaperRescaledFiles* rescaled_files,
17400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    bool* success,
17410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    gfx::ImageSkia* small_wallpaper_image,
17420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    gfx::ImageSkia* large_wallpaper_image) {
17430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  *success = true;
17440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
17455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  *success &= ResizeAndSaveWallpaper(*image,
17460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                     rescaled_files->path_rescaled_small(),
17470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                     ash::WALLPAPER_LAYOUT_STRETCH,
17480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                     kSmallWallpaperMaxWidth,
17490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                     kSmallWallpaperMaxHeight,
17500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                     small_wallpaper_image);
17510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
17525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  *success &= ResizeAndSaveWallpaper(*image,
17530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                     rescaled_files->path_rescaled_large(),
17540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                     ash::WALLPAPER_LAYOUT_STRETCH,
17550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                     kLargeWallpaperMaxWidth,
17560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                     kLargeWallpaperMaxHeight,
17570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                     large_wallpaper_image);
17580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
17590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
17600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid WallpaperManager::OnCustomizedDefaultWallpaperResized(
17610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const GURL& wallpaper_url,
17620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    scoped_ptr<CustomizedWallpaperRescaledFiles> rescaled_files,
17630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    scoped_ptr<bool> success,
17640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    scoped_ptr<gfx::ImageSkia> small_wallpaper_image,
17650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    scoped_ptr<gfx::ImageSkia> large_wallpaper_image) {
17660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
17670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(rescaled_files);
17680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(success.get());
17690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!*success) {
17700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    LOG(WARNING) << "Failed to save resized customized default wallpaper";
17710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
17720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
17730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  PrefService* pref_service = g_browser_process->local_state();
17740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  pref_service->SetString(prefs::kCustomizationDefaultWallpaperURL,
17750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                          wallpaper_url.spec());
17760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  SetDefaultWallpaperPath(rescaled_files->path_rescaled_small(),
17770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                          small_wallpaper_image.Pass(),
17780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                          rescaled_files->path_rescaled_large(),
17790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                          large_wallpaper_image.Pass());
17800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  VLOG(1) << "Customized default wallpaper applied.";
17810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
17820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
17835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)WallpaperManager::PendingWallpaper* WallpaperManager::GetPendingWallpaper(
17845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const std::string& user_id,
17855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool delayed) {
17865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!pending_inactive_) {
17875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    loading_.push_back(new WallpaperManager::PendingWallpaper(
17885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        (delayed ? GetWallpaperLoadDelay()
17895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 : base::TimeDelta::FromMilliseconds(0)),
17905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        user_id));
17911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    pending_inactive_ = loading_.back().get();
17925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
17935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return pending_inactive_;
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1796cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void WallpaperManager::RemovePendingWallpaperFromList(
1797cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    PendingWallpaper* pending) {
1798cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(loading_.size() > 0);
1799cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (WallpaperManager::PendingList::iterator i = loading_.begin();
1800cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       i != loading_.end();
1801cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       ++i) {
1802cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (i->get() == pending) {
1803cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      loading_.erase(i);
1804cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      break;
1805cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
1806cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
1807cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1808cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (loading_.empty())
1809cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FOR_EACH_OBSERVER(Observer, observers_, OnPendingListEmptyForTesting());
1810cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1811cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
18120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid WallpaperManager::SetCustomizedDefaultWallpaper(
18130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const GURL& wallpaper_url,
18140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const base::FilePath& downloaded_file,
18150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const base::FilePath& resized_directory) {
18160529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Should fail if this ever happens in tests.
18170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  DCHECK(wallpaper_url.is_valid());
18180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!wallpaper_url.is_valid()) {
18190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (!wallpaper_url.is_empty()) {
18200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      LOG(WARNING) << "Invalid Customized Wallpaper URL '"
18210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                   << wallpaper_url.spec() << "'";
18220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
18230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    return;
18240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
18250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  std::string downloaded_file_name = downloaded_file.BaseName().value();
18260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<CustomizedWallpaperRescaledFiles> rescaled_files(
18270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      new CustomizedWallpaperRescaledFiles(
18280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          downloaded_file,
18290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          resized_directory.Append(downloaded_file_name +
18300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                   kSmallWallpaperSuffix),
18310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          resized_directory.Append(downloaded_file_name +
18320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                                   kLargeWallpaperSuffix)));
18330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
18340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::Closure check_file_exists = rescaled_files->CreateCheckerClosure();
18350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  base::Closure on_checked_closure =
18360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      base::Bind(&WallpaperManager::SetCustomizedDefaultWallpaperAfterCheck,
18370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 weak_factory_.GetWeakPtr(),
18380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 wallpaper_url,
18390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 downloaded_file,
18400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                 base::Passed(rescaled_files.Pass()));
18410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (!BrowserThread::PostBlockingPoolTaskAndReply(
18420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          FROM_HERE, check_file_exists, on_checked_closure)) {
18430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    LOG(WARNING) << "Failed to start check CheckCustomizedWallpaperFilesExist.";
18440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
18450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
18460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1847cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)size_t WallpaperManager::GetPendingListSizeForTesting() const {
1848cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return loading_.size();
1849cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1850cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1851c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid WallpaperManager::SetDefaultWallpaperPathsFromCommandLine(
1852c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    base::CommandLine* command_line) {
1853c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  default_small_wallpaper_file_ = command_line->GetSwitchValuePath(
1854c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      ash::switches::kAshDefaultWallpaperSmall);
1855c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  default_large_wallpaper_file_ = command_line->GetSwitchValuePath(
1856c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      ash::switches::kAshDefaultWallpaperLarge);
1857c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  guest_small_wallpaper_file_ =
1858c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      command_line->GetSwitchValuePath(ash::switches::kAshGuestWallpaperSmall);
1859c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  guest_large_wallpaper_file_ =
1860c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      command_line->GetSwitchValuePath(ash::switches::kAshGuestWallpaperLarge);
1861c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  default_wallpaper_image_.reset();
1862c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
1863c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1864c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid WallpaperManager::OnDefaultWallpaperDecoded(
1865c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const base::FilePath& path,
1866c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const ash::WallpaperLayout layout,
1867116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_ptr<user_manager::UserImage>* result_out,
1868c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    MovableOnDestroyCallbackHolder on_finish,
1869116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const user_manager::UserImage& user_image) {
1870116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  result_out->reset(new user_manager::UserImage(user_image));
1871c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ash::Shell::GetInstance()->desktop_background_controller()->SetWallpaperImage(
18725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      user_image.image(), layout);
1873c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
1874c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1875c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid WallpaperManager::StartLoadAndSetDefaultWallpaper(
1876c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const base::FilePath& path,
1877c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const ash::WallpaperLayout layout,
1878c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    MovableOnDestroyCallbackHolder on_finish,
1879116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_ptr<user_manager::UserImage>* result_out) {
1880c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  wallpaper_loader_->Start(
1881c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      path.value(),
1882c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      0,  // Do not crop.
1883c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      base::Bind(&WallpaperManager::OnDefaultWallpaperDecoded,
1884c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                 weak_factory_.GetWeakPtr(),
1885c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                 path,
1886c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                 layout,
1887c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                 base::Unretained(result_out),
1888c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                 base::Passed(on_finish.Pass())));
1889c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
1890c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1891c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochconst char* WallpaperManager::GetCustomWallpaperSubdirForCurrentResolution() {
1892c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  WallpaperResolution resolution = GetAppropriateResolution();
1893c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  return resolution == WALLPAPER_RESOLUTION_SMALL ? kSmallWallpaperSubDir
1894c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                                  : kLargeWallpaperSubDir;
1895c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
1896c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
18970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid WallpaperManager::SetDefaultWallpaperPath(
18980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const base::FilePath& default_small_wallpaper_file,
18990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    scoped_ptr<gfx::ImageSkia> small_wallpaper_image,
19000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const base::FilePath& default_large_wallpaper_file,
19010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    scoped_ptr<gfx::ImageSkia> large_wallpaper_image) {
19020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  default_small_wallpaper_file_ = default_small_wallpaper_file;
19030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  default_large_wallpaper_file_ = default_large_wallpaper_file;
19040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
19050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  ash::DesktopBackgroundController* dbc =
19060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      ash::Shell::GetInstance()->desktop_background_controller();
19070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
19080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // |need_update_screen| is true if the previous default wallpaper is visible
19090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // now, so we need to update wallpaper on the screen.
19100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  //
19110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // Layout is ignored here, so ash::WALLPAPER_LAYOUT_CENTER is used
19120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  // as a placeholder only.
19130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  const bool need_update_screen =
19140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      default_wallpaper_image_.get() &&
1915cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      dbc->WallpaperIsAlreadyLoaded(default_wallpaper_image_->image(),
1916cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    false /* compare_layouts */,
1917cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                    ash::WALLPAPER_LAYOUT_CENTER);
19180529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
19190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  default_wallpaper_image_.reset();
19200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (GetAppropriateResolution() == WALLPAPER_RESOLUTION_SMALL) {
19210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (small_wallpaper_image) {
1922116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      default_wallpaper_image_.reset(
1923116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          new user_manager::UserImage(*small_wallpaper_image));
19240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      default_wallpaper_image_->set_file_path(
19250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          default_small_wallpaper_file.value());
19260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
19270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  } else {
19280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (large_wallpaper_image) {
1929116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      default_wallpaper_image_.reset(
1930116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          new user_manager::UserImage(*large_wallpaper_image));
19310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      default_wallpaper_image_->set_file_path(
19320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch          default_large_wallpaper_file.value());
19330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    }
19340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
19350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
19360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  if (need_update_screen) {
19370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    DoSetDefaultWallpaper(std::string(),
19380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                          MovableOnDestroyCallbackHolder().Pass());
19390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
19400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
19410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1942cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void WallpaperManager::CreateSolidDefaultWallpaper() {
1943cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  loaded_wallpapers_++;
1944cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SkBitmap bitmap;
1945116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bitmap.allocN32Pixels(1, 1);
1946cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bitmap.eraseColor(kDefaultWallpaperColor);
1947cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const gfx::ImageSkia image = gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
1948116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  default_wallpaper_image_.reset(new user_manager::UserImage(image));
1949cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
1950cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
19517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}  // namespace chromeos
1952