1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/extensions/wallpaper_private_api.h"
9 #include "ash/ash_switches.h"
10 #include "ash/desktop_background/desktop_background_controller.h"
11 #include "ash/shell.h"
12 #include "ash/wm/mru_window_tracker.h"
13 #include "ash/wm/window_state.h"
14 #include "ash/wm/window_util.h"
15 #include "base/command_line.h"
16 #include "base/file_util.h"
17 #include "base/files/file_enumerator.h"
18 #include "base/memory/scoped_ptr.h"
19 #include "base/path_service.h"
20 #include "base/strings/string_number_conversions.h"
21 #include "base/strings/stringprintf.h"
22 #include "base/threading/worker_pool.h"
23 #include "chrome/browser/browser_process.h"
24 #include "chrome/browser/chromeos/login/user.h"
25 #include "chrome/browser/chromeos/login/user_image.h"
26 #include "chrome/browser/chromeos/login/user_manager.h"
27 #include "chrome/browser/chromeos/login/wallpaper_manager.h"
28 #include "chrome/common/chrome_paths.h"
29 #include "content/public/browser/browser_thread.h"
30 #include "extensions/browser/event_router.h"
31 #include "grit/app_locale_settings.h"
32 #include "grit/generated_resources.h"
33 #include "grit/platform_locale_settings.h"
34 #include "ui/base/l10n/l10n_util.h"
35 #include "ui/base/webui/web_ui_util.h"
38 using base::BinaryValue;
39 using content::BrowserThread;
40 namespace wallpaper_private = extensions::api::wallpaper_private;
41 namespace set_wallpaper_if_exists = wallpaper_private::SetWallpaperIfExists;
42 namespace set_wallpaper = wallpaper_private::SetWallpaper;
43 namespace set_custom_wallpaper = wallpaper_private::SetCustomWallpaper;
44 namespace set_custom_wallpaper_layout =
45 wallpaper_private::SetCustomWallpaperLayout;
46 namespace get_thumbnail = wallpaper_private::GetThumbnail;
47 namespace save_thumbnail = wallpaper_private::SaveThumbnail;
48 namespace get_offline_wallpaper_list =
49 wallpaper_private::GetOfflineWallpaperList;
53 #if defined(GOOGLE_CHROME_BUILD)
54 const char kWallpaperManifestBaseURL[] = "https://commondatastorage.googleapis."
55 "com/chromeos-wallpaper-public/manifest_";
58 bool IsOEMDefaultWallpaper() {
59 return CommandLine::ForCurrentProcess()->HasSwitch(
60 ash::switches::kAshDefaultWallpaperIsOem);
63 // Saves |data| as |file_name| to directory with |key|. Return false if the
64 // directory can not be found/created or failed to write file.
65 bool SaveData(int key, const std::string& file_name, const std::string& data) {
66 base::FilePath data_dir;
67 CHECK(PathService::Get(key, &data_dir));
68 if (!base::DirectoryExists(data_dir) &&
69 !base::CreateDirectory(data_dir)) {
72 base::FilePath file_path = data_dir.Append(file_name);
74 return base::PathExists(file_path) ||
75 (base::WriteFile(file_path, data.c_str(), data.size()) != -1);
78 // Gets |file_name| from directory with |key|. Return false if the directory can
79 // not be found or failed to read file to string |data|. Note if the |file_name|
80 // can not be found in the directory, return true with empty |data|. It is
81 // expected that we may try to access file which did not saved yet.
82 bool GetData(const base::FilePath& path, std::string* data) {
83 base::FilePath data_dir = path.DirName();
84 if (!base::DirectoryExists(data_dir) &&
85 !base::CreateDirectory(data_dir))
88 return !base::PathExists(path) ||
89 base::ReadFileToString(path, data);
92 // WindowStateManager remembers which windows have been minimized in order to
93 // restore them when the wallpaper viewer is hidden.
94 class WindowStateManager : public aura::WindowObserver {
96 typedef std::map<std::string, std::set<aura::Window*> >
97 UserIDHashWindowListMap;
99 // Minimizes all windows except the active window.
100 static void MinimizeInactiveWindows(const std::string& user_id_hash);
102 // Unminimizes all minimized windows restoring them to their previous state.
103 // This should only be called after calling MinimizeInactiveWindows.
104 static void RestoreWindows(const std::string& user_id_hash);
107 WindowStateManager();
109 virtual ~WindowStateManager();
111 // Store all unminimized windows except |active_window| and minimize them.
112 // All the windows are saved in a map and the key value is |user_id_hash|.
113 void BuildWindowListAndMinimizeInactiveForUser(
114 const std::string& user_id_hash, aura::Window* active_window);
116 // Unminimize all the stored windows for |user_id_hash|.
117 void RestoreMinimizedWindows(const std::string& user_id_hash);
119 // Remove the observer from |window| if |window| is no longer referenced in
120 // user_id_hash_window_list_map_.
121 void RemoveObserverIfUnreferenced(aura::Window* window);
123 // aura::WindowObserver overrides.
124 virtual void OnWindowDestroyed(aura::Window* window) OVERRIDE;
126 // Map of user id hash and associated list of minimized windows.
127 UserIDHashWindowListMap user_id_hash_window_list_map_;
129 DISALLOW_COPY_AND_ASSIGN(WindowStateManager);
133 WindowStateManager* g_window_state_manager = NULL;
136 void WindowStateManager::MinimizeInactiveWindows(
137 const std::string& user_id_hash) {
138 if (!g_window_state_manager)
139 g_window_state_manager = new WindowStateManager();
140 g_window_state_manager->BuildWindowListAndMinimizeInactiveForUser(
141 user_id_hash, ash::wm::GetActiveWindow());
145 void WindowStateManager::RestoreWindows(const std::string& user_id_hash) {
146 if (!g_window_state_manager) {
147 DCHECK(false) << "This should only be called after calling "
148 << "MinimizeInactiveWindows.";
152 g_window_state_manager->RestoreMinimizedWindows(user_id_hash);
153 if (g_window_state_manager->user_id_hash_window_list_map_.empty()) {
154 delete g_window_state_manager;
155 g_window_state_manager = NULL;
159 WindowStateManager::WindowStateManager() {}
161 WindowStateManager::~WindowStateManager() {}
163 void WindowStateManager::BuildWindowListAndMinimizeInactiveForUser(
164 const std::string& user_id_hash, aura::Window* active_window) {
165 if (user_id_hash_window_list_map_.find(user_id_hash) ==
166 user_id_hash_window_list_map_.end()) {
167 user_id_hash_window_list_map_[user_id_hash] = std::set<aura::Window*>();
169 std::set<aura::Window*>* results =
170 &user_id_hash_window_list_map_[user_id_hash];
172 std::vector<aura::Window*> windows =
173 ash::MruWindowTracker::BuildWindowList(false);
175 for (std::vector<aura::Window*>::iterator iter = windows.begin();
176 iter != windows.end(); ++iter) {
177 // Ignore active window and minimized windows.
178 if (*iter == active_window || ash::wm::GetWindowState(*iter)->IsMinimized())
181 // TODO(bshe): Add WindowStateObserver too. http://crbug.com/323252
182 if (!(*iter)->HasObserver(this))
183 (*iter)->AddObserver(this);
185 results->insert(*iter);
186 ash::wm::GetWindowState(*iter)->Minimize();
190 void WindowStateManager::RestoreMinimizedWindows(
191 const std::string& user_id_hash) {
192 UserIDHashWindowListMap::iterator it =
193 user_id_hash_window_list_map_.find(user_id_hash);
194 if (it == user_id_hash_window_list_map_.end()) {
195 DCHECK(false) << "This should only be called after calling "
196 << "MinimizeInactiveWindows.";
200 std::set<aura::Window*> removed_windows;
201 removed_windows.swap(it->second);
202 user_id_hash_window_list_map_.erase(it);
204 for (std::set<aura::Window*>::iterator iter = removed_windows.begin();
205 iter != removed_windows.end(); ++iter) {
206 ash::wm::GetWindowState(*iter)->Unminimize();
207 RemoveObserverIfUnreferenced(*iter);
211 void WindowStateManager::RemoveObserverIfUnreferenced(aura::Window* window) {
212 for (UserIDHashWindowListMap::iterator iter =
213 user_id_hash_window_list_map_.begin();
214 iter != user_id_hash_window_list_map_.end();
216 if (iter->second.find(window) != iter->second.end())
219 // Remove observer if |window| is not observed by any users.
220 window->RemoveObserver(this);
223 void WindowStateManager::OnWindowDestroyed(aura::Window* window) {
224 for (UserIDHashWindowListMap::iterator iter =
225 user_id_hash_window_list_map_.begin();
226 iter != user_id_hash_window_list_map_.end();
228 iter->second.erase(window);
234 bool WallpaperPrivateGetStringsFunction::RunSync() {
235 base::DictionaryValue* dict = new base::DictionaryValue();
238 #define SET_STRING(id, idr) \
239 dict->SetString(id, l10n_util::GetStringUTF16(idr))
240 SET_STRING("webFontFamily", IDS_WEB_FONT_FAMILY);
241 SET_STRING("webFontSize", IDS_WEB_FONT_SIZE);
242 SET_STRING("allCategoryLabel", IDS_WALLPAPER_MANAGER_ALL_CATEGORY_LABEL);
243 SET_STRING("deleteCommandLabel", IDS_WALLPAPER_MANAGER_DELETE_COMMAND_LABEL);
244 SET_STRING("customCategoryLabel",
245 IDS_WALLPAPER_MANAGER_CUSTOM_CATEGORY_LABEL);
246 SET_STRING("selectCustomLabel",
247 IDS_WALLPAPER_MANAGER_SELECT_CUSTOM_LABEL);
248 SET_STRING("positionLabel", IDS_WALLPAPER_MANAGER_POSITION_LABEL);
249 SET_STRING("colorLabel", IDS_WALLPAPER_MANAGER_COLOR_LABEL);
250 SET_STRING("centerCroppedLayout",
251 IDS_OPTIONS_WALLPAPER_CENTER_CROPPED_LAYOUT);
252 SET_STRING("centerLayout", IDS_OPTIONS_WALLPAPER_CENTER_LAYOUT);
253 SET_STRING("stretchLayout", IDS_OPTIONS_WALLPAPER_STRETCH_LAYOUT);
254 SET_STRING("connectionFailed", IDS_WALLPAPER_MANAGER_ACCESS_FAIL);
255 SET_STRING("downloadFailed", IDS_WALLPAPER_MANAGER_DOWNLOAD_FAIL);
256 SET_STRING("downloadCanceled", IDS_WALLPAPER_MANAGER_DOWNLOAD_CANCEL);
257 SET_STRING("customWallpaperWarning",
258 IDS_WALLPAPER_MANAGER_SHOW_CUSTOM_WALLPAPER_ON_START_WARNING);
259 SET_STRING("accessFileFailure", IDS_WALLPAPER_MANAGER_ACCESS_FILE_FAILURE);
260 SET_STRING("invalidWallpaper", IDS_WALLPAPER_MANAGER_INVALID_WALLPAPER);
261 SET_STRING("surpriseMeLabel", IDS_WALLPAPER_MANAGER_SURPRISE_ME_LABEL);
262 SET_STRING("learnMore", IDS_LEARN_MORE);
265 webui::SetFontAndTextDirection(dict);
267 chromeos::WallpaperManager* wallpaper_manager =
268 chromeos::WallpaperManager::Get();
269 chromeos::WallpaperInfo info;
271 if (wallpaper_manager->GetLoggedInUserWallpaperInfo(&info))
272 dict->SetString("currentWallpaper", info.file);
274 #if defined(GOOGLE_CHROME_BUILD)
275 dict->SetString("manifestBaseURL", kWallpaperManifestBaseURL);
278 dict->SetBoolean("isOEMDefaultWallpaper", IsOEMDefaultWallpaper());
282 WallpaperPrivateSetWallpaperIfExistsFunction::
283 WallpaperPrivateSetWallpaperIfExistsFunction() {}
285 WallpaperPrivateSetWallpaperIfExistsFunction::
286 ~WallpaperPrivateSetWallpaperIfExistsFunction() {}
288 bool WallpaperPrivateSetWallpaperIfExistsFunction::RunAsync() {
289 params = set_wallpaper_if_exists::Params::Create(*args_);
290 EXTENSION_FUNCTION_VALIDATE(params);
292 user_id_ = chromeos::UserManager::Get()->GetActiveUser()->email();
294 base::FilePath wallpaper_path;
295 base::FilePath fallback_path;
296 chromeos::WallpaperManager::WallpaperResolution resolution =
297 chromeos::WallpaperManager::GetAppropriateResolution();
299 std::string file_name = GURL(params->url).ExtractFileName();
300 CHECK(PathService::Get(chrome::DIR_CHROMEOS_WALLPAPERS,
302 fallback_path = wallpaper_path.Append(file_name);
303 if (params->layout != wallpaper_private::WALLPAPER_LAYOUT_STRETCH &&
304 resolution == chromeos::WallpaperManager::WALLPAPER_RESOLUTION_SMALL) {
305 file_name = base::FilePath(file_name).InsertBeforeExtension(
306 chromeos::kSmallWallpaperSuffix).value();
308 wallpaper_path = wallpaper_path.Append(file_name);
310 sequence_token_ = BrowserThread::GetBlockingPool()->
311 GetNamedSequenceToken(chromeos::kWallpaperSequenceTokenName);
312 scoped_refptr<base::SequencedTaskRunner> task_runner =
313 BrowserThread::GetBlockingPool()->
314 GetSequencedTaskRunnerWithShutdownBehavior(sequence_token_,
315 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
317 task_runner->PostTask(FROM_HERE,
319 &WallpaperPrivateSetWallpaperIfExistsFunction::
320 ReadFileAndInitiateStartDecode,
321 this, wallpaper_path, fallback_path));
325 void WallpaperPrivateSetWallpaperIfExistsFunction::
326 ReadFileAndInitiateStartDecode(const base::FilePath& file_path,
327 const base::FilePath& fallback_path) {
328 DCHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread(
331 base::FilePath path = file_path;
333 if (!base::PathExists(file_path))
334 path = fallback_path;
336 if (base::PathExists(path) &&
337 base::ReadFileToString(path, &data)) {
338 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
339 base::Bind(&WallpaperPrivateSetWallpaperIfExistsFunction::StartDecode,
343 std::string error = base::StringPrintf(
344 "Failed to set wallpaper %s from file system.",
345 path.BaseName().value().c_str());
346 BrowserThread::PostTask(
347 BrowserThread::UI, FROM_HERE,
348 base::Bind(&WallpaperPrivateSetWallpaperIfExistsFunction::OnFileNotExists,
352 void WallpaperPrivateSetWallpaperIfExistsFunction::OnWallpaperDecoded(
353 const gfx::ImageSkia& image) {
354 // Set unsafe_wallpaper_decoder_ to null since the decoding already finished.
355 unsafe_wallpaper_decoder_ = NULL;
357 chromeos::WallpaperManager* wallpaper_manager =
358 chromeos::WallpaperManager::Get();
359 ash::WallpaperLayout layout = wallpaper_api_util::GetLayoutEnum(
360 wallpaper_private::ToString(params->layout));
362 bool update_wallpaper =
363 user_id_ == chromeos::UserManager::Get()->GetActiveUser()->email();
364 wallpaper_manager->SetWallpaperFromImageSkia(
365 user_id_, image, layout, update_wallpaper);
367 !chromeos::UserManager::Get()->IsCurrentUserNonCryptohomeDataEphemeral();
368 chromeos::WallpaperInfo info = {
371 chromeos::User::ONLINE,
372 base::Time::Now().LocalMidnight()
374 wallpaper_manager->SetUserWallpaperInfo(user_id_, info, is_persistent);
375 SetResult(base::Value::CreateBooleanValue(true));
379 void WallpaperPrivateSetWallpaperIfExistsFunction::OnFileNotExists(
380 const std::string& error) {
381 SetResult(base::Value::CreateBooleanValue(false));
385 WallpaperPrivateSetWallpaperFunction::WallpaperPrivateSetWallpaperFunction() {
388 WallpaperPrivateSetWallpaperFunction::~WallpaperPrivateSetWallpaperFunction() {
391 bool WallpaperPrivateSetWallpaperFunction::RunAsync() {
392 params = set_wallpaper::Params::Create(*args_);
393 EXTENSION_FUNCTION_VALIDATE(params);
395 // Gets email address while at UI thread.
396 user_id_ = chromeos::UserManager::Get()->GetActiveUser()->email();
398 StartDecode(params->wallpaper);
403 void WallpaperPrivateSetWallpaperFunction::OnWallpaperDecoded(
404 const gfx::ImageSkia& image) {
406 // Set unsafe_wallpaper_decoder_ to null since the decoding already finished.
407 unsafe_wallpaper_decoder_ = NULL;
409 sequence_token_ = BrowserThread::GetBlockingPool()->
410 GetNamedSequenceToken(chromeos::kWallpaperSequenceTokenName);
411 scoped_refptr<base::SequencedTaskRunner> task_runner =
412 BrowserThread::GetBlockingPool()->
413 GetSequencedTaskRunnerWithShutdownBehavior(sequence_token_,
414 base::SequencedWorkerPool::BLOCK_SHUTDOWN);
416 task_runner->PostTask(FROM_HERE,
417 base::Bind(&WallpaperPrivateSetWallpaperFunction::SaveToFile, this));
420 void WallpaperPrivateSetWallpaperFunction::SaveToFile() {
421 DCHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread(
423 std::string file_name = GURL(params->url).ExtractFileName();
424 if (SaveData(chrome::DIR_CHROMEOS_WALLPAPERS, file_name, params->wallpaper)) {
425 wallpaper_.EnsureRepsForSupportedScales();
426 scoped_ptr<gfx::ImageSkia> deep_copy(wallpaper_.DeepCopy());
427 // ImageSkia is not RefCountedThreadSafe. Use a deep copied ImageSkia if
428 // post to another thread.
429 BrowserThread::PostTask(
432 base::Bind(&WallpaperPrivateSetWallpaperFunction::SetDecodedWallpaper,
434 base::Passed(deep_copy.Pass())));
436 base::FilePath wallpaper_dir;
437 CHECK(PathService::Get(chrome::DIR_CHROMEOS_WALLPAPERS, &wallpaper_dir));
438 base::FilePath file_path = wallpaper_dir.Append(
439 file_name).InsertBeforeExtension(chromeos::kSmallWallpaperSuffix);
440 if (base::PathExists(file_path))
442 // Generates and saves small resolution wallpaper. Uses CENTER_CROPPED to
443 // maintain the aspect ratio after resize.
444 chromeos::WallpaperManager::Get()->ResizeAndSaveWallpaper(
447 ash::WALLPAPER_LAYOUT_CENTER_CROPPED,
448 chromeos::kSmallWallpaperMaxWidth,
449 chromeos::kSmallWallpaperMaxHeight,
452 std::string error = base::StringPrintf(
453 "Failed to create/write wallpaper to %s.", file_name.c_str());
454 BrowserThread::PostTask(
455 BrowserThread::UI, FROM_HERE,
456 base::Bind(&WallpaperPrivateSetWallpaperFunction::OnFailure,
461 void WallpaperPrivateSetWallpaperFunction::SetDecodedWallpaper(
462 scoped_ptr<gfx::ImageSkia> image) {
463 chromeos::WallpaperManager* wallpaper_manager =
464 chromeos::WallpaperManager::Get();
466 ash::WallpaperLayout layout = wallpaper_api_util::GetLayoutEnum(
467 wallpaper_private::ToString(params->layout));
469 bool update_wallpaper =
470 user_id_ == chromeos::UserManager::Get()->GetActiveUser()->email();
471 wallpaper_manager->SetWallpaperFromImageSkia(
472 user_id_, *image.get(), layout, update_wallpaper);
475 !chromeos::UserManager::Get()->IsCurrentUserNonCryptohomeDataEphemeral();
476 chromeos::WallpaperInfo info = {
479 chromeos::User::ONLINE,
480 base::Time::Now().LocalMidnight()
482 wallpaper_manager->SetUserWallpaperInfo(user_id_, info, is_persistent);
486 WallpaperPrivateResetWallpaperFunction::
487 WallpaperPrivateResetWallpaperFunction() {}
489 WallpaperPrivateResetWallpaperFunction::
490 ~WallpaperPrivateResetWallpaperFunction() {}
492 bool WallpaperPrivateResetWallpaperFunction::RunAsync() {
493 chromeos::WallpaperManager* wallpaper_manager =
494 chromeos::WallpaperManager::Get();
495 chromeos::UserManager* user_manager = chromeos::UserManager::Get();
497 std::string user_id = user_manager->GetActiveUser()->email();
498 wallpaper_manager->RemoveUserWallpaperInfo(user_id);
500 chromeos::WallpaperInfo info = {
502 ash::WALLPAPER_LAYOUT_CENTER,
503 chromeos::User::DEFAULT,
504 base::Time::Now().LocalMidnight()
507 !user_manager->IsCurrentUserNonCryptohomeDataEphemeral();
508 wallpaper_manager->SetUserWallpaperInfo(user_id, info, is_persistent);
510 wallpaper_manager->SetDefaultWallpaperNow(user_id);
514 WallpaperPrivateSetCustomWallpaperFunction::
515 WallpaperPrivateSetCustomWallpaperFunction() {}
517 WallpaperPrivateSetCustomWallpaperFunction::
518 ~WallpaperPrivateSetCustomWallpaperFunction() {}
520 bool WallpaperPrivateSetCustomWallpaperFunction::RunAsync() {
521 params = set_custom_wallpaper::Params::Create(*args_);
522 EXTENSION_FUNCTION_VALIDATE(params);
524 // Gets email address and username hash while at UI thread.
525 user_id_ = chromeos::UserManager::Get()->GetActiveUser()->email();
527 chromeos::UserManager::Get()->GetActiveUser()->username_hash();
529 StartDecode(params->wallpaper);
534 void WallpaperPrivateSetCustomWallpaperFunction::OnWallpaperDecoded(
535 const gfx::ImageSkia& image) {
536 chromeos::WallpaperManager* wallpaper_manager =
537 chromeos::WallpaperManager::Get();
538 base::FilePath thumbnail_path = wallpaper_manager->GetCustomWallpaperPath(
539 chromeos::kThumbnailWallpaperSubDir, user_id_hash_, params->file_name);
541 sequence_token_ = BrowserThread::GetBlockingPool()->
542 GetNamedSequenceToken(chromeos::kWallpaperSequenceTokenName);
543 scoped_refptr<base::SequencedTaskRunner> task_runner =
544 BrowserThread::GetBlockingPool()->
545 GetSequencedTaskRunnerWithShutdownBehavior(sequence_token_,
546 base::SequencedWorkerPool::BLOCK_SHUTDOWN);
548 ash::WallpaperLayout layout = wallpaper_api_util::GetLayoutEnum(
549 wallpaper_private::ToString(params->layout));
551 bool update_wallpaper =
552 user_id_ == chromeos::UserManager::Get()->GetActiveUser()->email();
553 wallpaper_manager->SetCustomWallpaper(user_id_,
557 chromeos::User::CUSTOMIZED,
560 unsafe_wallpaper_decoder_ = NULL;
562 if (params->generate_thumbnail) {
563 image.EnsureRepsForSupportedScales();
564 scoped_ptr<gfx::ImageSkia> deep_copy(image.DeepCopy());
565 // Generates thumbnail before call api function callback. We can then
566 // request thumbnail in the javascript callback.
567 task_runner->PostTask(FROM_HERE,
569 &WallpaperPrivateSetCustomWallpaperFunction::GenerateThumbnail,
570 this, thumbnail_path, base::Passed(&deep_copy)));
576 void WallpaperPrivateSetCustomWallpaperFunction::GenerateThumbnail(
577 const base::FilePath& thumbnail_path, scoped_ptr<gfx::ImageSkia> image) {
578 DCHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread(
580 if (!base::PathExists(thumbnail_path.DirName()))
581 base::CreateDirectory(thumbnail_path.DirName());
583 scoped_refptr<base::RefCountedBytes> data;
584 chromeos::WallpaperManager::Get()->ResizeImage(
586 ash::WALLPAPER_LAYOUT_STRETCH,
587 chromeos::kWallpaperThumbnailWidth,
588 chromeos::kWallpaperThumbnailHeight,
591 BrowserThread::PostTask(
592 BrowserThread::UI, FROM_HERE,
594 &WallpaperPrivateSetCustomWallpaperFunction::ThumbnailGenerated,
598 void WallpaperPrivateSetCustomWallpaperFunction::ThumbnailGenerated(
599 base::RefCountedBytes* data) {
600 BinaryValue* result = BinaryValue::CreateWithCopiedBuffer(
601 reinterpret_cast<const char*>(data->front()), data->size());
606 WallpaperPrivateSetCustomWallpaperLayoutFunction::
607 WallpaperPrivateSetCustomWallpaperLayoutFunction() {}
609 WallpaperPrivateSetCustomWallpaperLayoutFunction::
610 ~WallpaperPrivateSetCustomWallpaperLayoutFunction() {}
612 bool WallpaperPrivateSetCustomWallpaperLayoutFunction::RunAsync() {
613 scoped_ptr<set_custom_wallpaper_layout::Params> params(
614 set_custom_wallpaper_layout::Params::Create(*args_));
615 EXTENSION_FUNCTION_VALIDATE(params);
617 chromeos::WallpaperManager* wallpaper_manager =
618 chromeos::WallpaperManager::Get();
619 chromeos::WallpaperInfo info;
620 wallpaper_manager->GetLoggedInUserWallpaperInfo(&info);
621 if (info.type != chromeos::User::CUSTOMIZED) {
622 SetError("Only custom wallpaper can change layout.");
626 info.layout = wallpaper_api_util::GetLayoutEnum(
627 wallpaper_private::ToString(params->layout));
629 std::string email = chromeos::UserManager::Get()->GetActiveUser()->email();
631 !chromeos::UserManager::Get()->IsCurrentUserNonCryptohomeDataEphemeral();
632 wallpaper_manager->SetUserWallpaperInfo(email, info, is_persistent);
633 wallpaper_manager->UpdateWallpaper(false /* clear_cache */);
636 // Gets email address while at UI thread.
640 WallpaperPrivateMinimizeInactiveWindowsFunction::
641 WallpaperPrivateMinimizeInactiveWindowsFunction() {
644 WallpaperPrivateMinimizeInactiveWindowsFunction::
645 ~WallpaperPrivateMinimizeInactiveWindowsFunction() {
648 bool WallpaperPrivateMinimizeInactiveWindowsFunction::RunAsync() {
649 WindowStateManager::MinimizeInactiveWindows(
650 chromeos::UserManager::Get()->GetActiveUser()->username_hash());
654 WallpaperPrivateRestoreMinimizedWindowsFunction::
655 WallpaperPrivateRestoreMinimizedWindowsFunction() {
658 WallpaperPrivateRestoreMinimizedWindowsFunction::
659 ~WallpaperPrivateRestoreMinimizedWindowsFunction() {
662 bool WallpaperPrivateRestoreMinimizedWindowsFunction::RunAsync() {
663 WindowStateManager::RestoreWindows(
664 chromeos::UserManager::Get()->GetActiveUser()->username_hash());
668 WallpaperPrivateGetThumbnailFunction::WallpaperPrivateGetThumbnailFunction() {
671 WallpaperPrivateGetThumbnailFunction::~WallpaperPrivateGetThumbnailFunction() {
674 bool WallpaperPrivateGetThumbnailFunction::RunAsync() {
675 scoped_ptr<get_thumbnail::Params> params(
676 get_thumbnail::Params::Create(*args_));
677 EXTENSION_FUNCTION_VALIDATE(params);
679 base::FilePath thumbnail_path;
680 std::string email = chromeos::UserManager::Get()->GetActiveUser()->email();
681 if (params->source == get_thumbnail::Params::SOURCE_ONLINE) {
682 std::string file_name = GURL(params->url_or_file).ExtractFileName();
683 CHECK(PathService::Get(chrome::DIR_CHROMEOS_WALLPAPER_THUMBNAILS,
685 thumbnail_path = thumbnail_path.Append(file_name);
687 if (!IsOEMDefaultWallpaper()) {
688 SetError("No OEM wallpaper.");
693 // TODO(bshe): Small resolution wallpaper is used here as wallpaper
694 // thumbnail. We should either resize it or include a wallpaper thumbnail in
695 // addition to large and small wallpaper resolutions.
696 thumbnail_path = CommandLine::ForCurrentProcess()->GetSwitchValuePath(
697 ash::switches::kAshDefaultWallpaperSmall);
700 sequence_token_ = BrowserThread::GetBlockingPool()->
701 GetNamedSequenceToken(chromeos::kWallpaperSequenceTokenName);
702 scoped_refptr<base::SequencedTaskRunner> task_runner =
703 BrowserThread::GetBlockingPool()->
704 GetSequencedTaskRunnerWithShutdownBehavior(sequence_token_,
705 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
707 task_runner->PostTask(FROM_HERE,
708 base::Bind(&WallpaperPrivateGetThumbnailFunction::Get, this,
713 void WallpaperPrivateGetThumbnailFunction::Failure(
714 const std::string& file_name) {
715 SetError(base::StringPrintf("Failed to access wallpaper thumbnails for %s.",
720 void WallpaperPrivateGetThumbnailFunction::FileNotLoaded() {
724 void WallpaperPrivateGetThumbnailFunction::FileLoaded(
725 const std::string& data) {
726 BinaryValue* thumbnail = BinaryValue::CreateWithCopiedBuffer(data.c_str(),
728 SetResult(thumbnail);
732 void WallpaperPrivateGetThumbnailFunction::Get(const base::FilePath& path) {
733 DCHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread(
736 if (GetData(path, &data)) {
738 BrowserThread::PostTask(
739 BrowserThread::UI, FROM_HERE,
740 base::Bind(&WallpaperPrivateGetThumbnailFunction::FileNotLoaded, this));
742 BrowserThread::PostTask(
743 BrowserThread::UI, FROM_HERE,
744 base::Bind(&WallpaperPrivateGetThumbnailFunction::FileLoaded, this,
748 BrowserThread::PostTask(
749 BrowserThread::UI, FROM_HERE,
750 base::Bind(&WallpaperPrivateGetThumbnailFunction::Failure, this,
751 path.BaseName().value()));
755 WallpaperPrivateSaveThumbnailFunction::WallpaperPrivateSaveThumbnailFunction() {
758 WallpaperPrivateSaveThumbnailFunction::
759 ~WallpaperPrivateSaveThumbnailFunction() {}
761 bool WallpaperPrivateSaveThumbnailFunction::RunAsync() {
762 scoped_ptr<save_thumbnail::Params> params(
763 save_thumbnail::Params::Create(*args_));
764 EXTENSION_FUNCTION_VALIDATE(params);
766 sequence_token_ = BrowserThread::GetBlockingPool()->
767 GetNamedSequenceToken(chromeos::kWallpaperSequenceTokenName);
768 scoped_refptr<base::SequencedTaskRunner> task_runner =
769 BrowserThread::GetBlockingPool()->
770 GetSequencedTaskRunnerWithShutdownBehavior(sequence_token_,
771 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
773 task_runner->PostTask(FROM_HERE,
774 base::Bind(&WallpaperPrivateSaveThumbnailFunction::Save,
775 this, params->data, GURL(params->url).ExtractFileName()));
779 void WallpaperPrivateSaveThumbnailFunction::Failure(
780 const std::string& file_name) {
781 SetError(base::StringPrintf("Failed to create/write thumbnail of %s.",
786 void WallpaperPrivateSaveThumbnailFunction::Success() {
790 void WallpaperPrivateSaveThumbnailFunction::Save(const std::string& data,
791 const std::string& file_name) {
792 DCHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread(
794 if (SaveData(chrome::DIR_CHROMEOS_WALLPAPER_THUMBNAILS, file_name, data)) {
795 BrowserThread::PostTask(
796 BrowserThread::UI, FROM_HERE,
797 base::Bind(&WallpaperPrivateSaveThumbnailFunction::Success, this));
799 BrowserThread::PostTask(
800 BrowserThread::UI, FROM_HERE,
801 base::Bind(&WallpaperPrivateSaveThumbnailFunction::Failure,
806 WallpaperPrivateGetOfflineWallpaperListFunction::
807 WallpaperPrivateGetOfflineWallpaperListFunction() {
810 WallpaperPrivateGetOfflineWallpaperListFunction::
811 ~WallpaperPrivateGetOfflineWallpaperListFunction() {
814 bool WallpaperPrivateGetOfflineWallpaperListFunction::RunAsync() {
815 sequence_token_ = BrowserThread::GetBlockingPool()->
816 GetNamedSequenceToken(chromeos::kWallpaperSequenceTokenName);
817 scoped_refptr<base::SequencedTaskRunner> task_runner =
818 BrowserThread::GetBlockingPool()->
819 GetSequencedTaskRunnerWithShutdownBehavior(sequence_token_,
820 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN);
822 task_runner->PostTask(FROM_HERE,
823 base::Bind(&WallpaperPrivateGetOfflineWallpaperListFunction::GetList,
828 void WallpaperPrivateGetOfflineWallpaperListFunction::GetList() {
829 DCHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread(
831 std::vector<std::string> file_list;
832 base::FilePath wallpaper_dir;
833 CHECK(PathService::Get(chrome::DIR_CHROMEOS_WALLPAPERS, &wallpaper_dir));
834 if (base::DirectoryExists(wallpaper_dir)) {
835 base::FileEnumerator files(wallpaper_dir, false,
836 base::FileEnumerator::FILES);
837 for (base::FilePath current = files.Next(); !current.empty();
838 current = files.Next()) {
839 std::string file_name = current.BaseName().RemoveExtension().value();
840 // Do not add file name of small resolution wallpaper to the list.
841 if (!EndsWith(file_name, chromeos::kSmallWallpaperSuffix, true))
842 file_list.push_back(current.BaseName().value());
845 BrowserThread::PostTask(
846 BrowserThread::UI, FROM_HERE,
847 base::Bind(&WallpaperPrivateGetOfflineWallpaperListFunction::OnComplete,
851 void WallpaperPrivateGetOfflineWallpaperListFunction::OnComplete(
852 const std::vector<std::string>& file_list) {
853 base::ListValue* results = new base::ListValue();
854 results->AppendStrings(file_list);