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 (file_util::WriteFile(file_path
, data
.c_str(),
79 // Gets |file_name| from directory with |key|. Return false if the directory can
80 // not be found or failed to read file to string |data|. Note if the |file_name|
81 // can not be found in the directory, return true with empty |data|. It is
82 // expected that we may try to access file which did not saved yet.
83 bool GetData(const base::FilePath
& path
, std::string
* data
) {
84 base::FilePath data_dir
= path
.DirName();
85 if (!base::DirectoryExists(data_dir
) &&
86 !base::CreateDirectory(data_dir
))
89 return !base::PathExists(path
) ||
90 base::ReadFileToString(path
, data
);
93 // WindowStateManager remembers which windows have been minimized in order to
94 // restore them when the wallpaper viewer is hidden.
95 class WindowStateManager
: public aura::WindowObserver
{
97 typedef std::map
<std::string
, std::set
<aura::Window
*> >
98 UserIDHashWindowListMap
;
100 // Minimizes all windows except the active window.
101 static void MinimizeInactiveWindows(const std::string
& user_id_hash
);
103 // Unminimizes all minimized windows restoring them to their previous state.
104 // This should only be called after calling MinimizeInactiveWindows.
105 static void RestoreWindows(const std::string
& user_id_hash
);
108 WindowStateManager();
110 virtual ~WindowStateManager();
112 // Store all unminimized windows except |active_window| and minimize them.
113 // All the windows are saved in a map and the key value is |user_id_hash|.
114 void BuildWindowListAndMinimizeInactiveForUser(
115 const std::string
& user_id_hash
, aura::Window
* active_window
);
117 // Unminimize all the stored windows for |user_id_hash|.
118 void RestoreMinimizedWindows(const std::string
& user_id_hash
);
120 // Remove the observer from |window| if |window| is no longer referenced in
121 // user_id_hash_window_list_map_.
122 void RemoveObserverIfUnreferenced(aura::Window
* window
);
124 // aura::WindowObserver overrides.
125 virtual void OnWindowDestroyed(aura::Window
* window
) OVERRIDE
;
127 // Map of user id hash and associated list of minimized windows.
128 UserIDHashWindowListMap user_id_hash_window_list_map_
;
130 DISALLOW_COPY_AND_ASSIGN(WindowStateManager
);
134 WindowStateManager
* g_window_state_manager
= NULL
;
137 void WindowStateManager::MinimizeInactiveWindows(
138 const std::string
& user_id_hash
) {
139 if (!g_window_state_manager
)
140 g_window_state_manager
= new WindowStateManager();
141 g_window_state_manager
->BuildWindowListAndMinimizeInactiveForUser(
142 user_id_hash
, ash::wm::GetActiveWindow());
146 void WindowStateManager::RestoreWindows(const std::string
& user_id_hash
) {
147 if (!g_window_state_manager
) {
148 DCHECK(false) << "This should only be called after calling "
149 << "MinimizeInactiveWindows.";
153 g_window_state_manager
->RestoreMinimizedWindows(user_id_hash
);
154 if (g_window_state_manager
->user_id_hash_window_list_map_
.empty()) {
155 delete g_window_state_manager
;
156 g_window_state_manager
= NULL
;
160 WindowStateManager::WindowStateManager() {}
162 WindowStateManager::~WindowStateManager() {}
164 void WindowStateManager::BuildWindowListAndMinimizeInactiveForUser(
165 const std::string
& user_id_hash
, aura::Window
* active_window
) {
166 if (user_id_hash_window_list_map_
.find(user_id_hash
) ==
167 user_id_hash_window_list_map_
.end()) {
168 user_id_hash_window_list_map_
[user_id_hash
] = std::set
<aura::Window
*>();
170 std::set
<aura::Window
*>* results
=
171 &user_id_hash_window_list_map_
[user_id_hash
];
173 std::vector
<aura::Window
*> windows
=
174 ash::MruWindowTracker::BuildWindowList(false);
176 for (std::vector
<aura::Window
*>::iterator iter
= windows
.begin();
177 iter
!= windows
.end(); ++iter
) {
178 // Ignore active window and minimized windows.
179 if (*iter
== active_window
|| ash::wm::GetWindowState(*iter
)->IsMinimized())
182 // TODO(bshe): Add WindowStateObserver too. http://crbug.com/323252
183 if (!(*iter
)->HasObserver(this))
184 (*iter
)->AddObserver(this);
186 results
->insert(*iter
);
187 ash::wm::GetWindowState(*iter
)->Minimize();
191 void WindowStateManager::RestoreMinimizedWindows(
192 const std::string
& user_id_hash
) {
193 UserIDHashWindowListMap::iterator it
=
194 user_id_hash_window_list_map_
.find(user_id_hash
);
195 if (it
== user_id_hash_window_list_map_
.end()) {
196 DCHECK(false) << "This should only be called after calling "
197 << "MinimizeInactiveWindows.";
201 std::set
<aura::Window
*> removed_windows
;
202 removed_windows
.swap(it
->second
);
203 user_id_hash_window_list_map_
.erase(it
);
205 for (std::set
<aura::Window
*>::iterator iter
= removed_windows
.begin();
206 iter
!= removed_windows
.end(); ++iter
) {
207 ash::wm::GetWindowState(*iter
)->Unminimize();
208 RemoveObserverIfUnreferenced(*iter
);
212 void WindowStateManager::RemoveObserverIfUnreferenced(aura::Window
* window
) {
213 for (UserIDHashWindowListMap::iterator iter
=
214 user_id_hash_window_list_map_
.begin();
215 iter
!= user_id_hash_window_list_map_
.end();
217 if (iter
->second
.find(window
) != iter
->second
.end())
220 // Remove observer if |window| is not observed by any users.
221 window
->RemoveObserver(this);
224 void WindowStateManager::OnWindowDestroyed(aura::Window
* window
) {
225 for (UserIDHashWindowListMap::iterator iter
=
226 user_id_hash_window_list_map_
.begin();
227 iter
!= user_id_hash_window_list_map_
.end();
229 iter
->second
.erase(window
);
235 bool WallpaperPrivateGetStringsFunction::RunImpl() {
236 base::DictionaryValue
* dict
= new base::DictionaryValue();
239 #define SET_STRING(id, idr) \
240 dict->SetString(id, l10n_util::GetStringUTF16(idr))
241 SET_STRING("webFontFamily", IDS_WEB_FONT_FAMILY
);
242 SET_STRING("webFontSize", IDS_WEB_FONT_SIZE
);
243 SET_STRING("allCategoryLabel", IDS_WALLPAPER_MANAGER_ALL_CATEGORY_LABEL
);
244 SET_STRING("deleteCommandLabel", IDS_WALLPAPER_MANAGER_DELETE_COMMAND_LABEL
);
245 SET_STRING("customCategoryLabel",
246 IDS_WALLPAPER_MANAGER_CUSTOM_CATEGORY_LABEL
);
247 SET_STRING("selectCustomLabel",
248 IDS_WALLPAPER_MANAGER_SELECT_CUSTOM_LABEL
);
249 SET_STRING("positionLabel", IDS_WALLPAPER_MANAGER_POSITION_LABEL
);
250 SET_STRING("colorLabel", IDS_WALLPAPER_MANAGER_COLOR_LABEL
);
251 SET_STRING("centerCroppedLayout",
252 IDS_OPTIONS_WALLPAPER_CENTER_CROPPED_LAYOUT
);
253 SET_STRING("centerLayout", IDS_OPTIONS_WALLPAPER_CENTER_LAYOUT
);
254 SET_STRING("stretchLayout", IDS_OPTIONS_WALLPAPER_STRETCH_LAYOUT
);
255 SET_STRING("connectionFailed", IDS_WALLPAPER_MANAGER_ACCESS_FAIL
);
256 SET_STRING("downloadFailed", IDS_WALLPAPER_MANAGER_DOWNLOAD_FAIL
);
257 SET_STRING("downloadCanceled", IDS_WALLPAPER_MANAGER_DOWNLOAD_CANCEL
);
258 SET_STRING("customWallpaperWarning",
259 IDS_WALLPAPER_MANAGER_SHOW_CUSTOM_WALLPAPER_ON_START_WARNING
);
260 SET_STRING("accessFileFailure", IDS_WALLPAPER_MANAGER_ACCESS_FILE_FAILURE
);
261 SET_STRING("invalidWallpaper", IDS_WALLPAPER_MANAGER_INVALID_WALLPAPER
);
262 SET_STRING("surpriseMeLabel", IDS_WALLPAPER_MANAGER_SURPRISE_ME_LABEL
);
263 SET_STRING("learnMore", IDS_LEARN_MORE
);
266 webui::SetFontAndTextDirection(dict
);
268 chromeos::WallpaperManager
* wallpaper_manager
=
269 chromeos::WallpaperManager::Get();
270 chromeos::WallpaperInfo info
;
272 if (wallpaper_manager
->GetLoggedInUserWallpaperInfo(&info
))
273 dict
->SetString("currentWallpaper", info
.file
);
275 #if defined(GOOGLE_CHROME_BUILD)
276 dict
->SetString("manifestBaseURL", kWallpaperManifestBaseURL
);
279 dict
->SetBoolean("isOEMDefaultWallpaper", IsOEMDefaultWallpaper());
283 WallpaperPrivateSetWallpaperIfExistsFunction::
284 WallpaperPrivateSetWallpaperIfExistsFunction() {}
286 WallpaperPrivateSetWallpaperIfExistsFunction::
287 ~WallpaperPrivateSetWallpaperIfExistsFunction() {}
289 bool WallpaperPrivateSetWallpaperIfExistsFunction::RunImpl() {
290 params
= set_wallpaper_if_exists::Params::Create(*args_
);
291 EXTENSION_FUNCTION_VALIDATE(params
);
293 std::string email
= chromeos::UserManager::Get()->GetLoggedInUser()->email();
295 base::FilePath wallpaper_path
;
296 base::FilePath fallback_path
;
297 ash::WallpaperResolution resolution
= ash::Shell::GetInstance()->
298 desktop_background_controller()->GetAppropriateResolution();
300 std::string file_name
= GURL(params
->url
).ExtractFileName();
301 CHECK(PathService::Get(chrome::DIR_CHROMEOS_WALLPAPERS
,
303 fallback_path
= wallpaper_path
.Append(file_name
);
304 if (params
->layout
!= wallpaper_private::WALLPAPER_LAYOUT_STRETCH
&&
305 resolution
== ash::WALLPAPER_RESOLUTION_SMALL
) {
306 file_name
= base::FilePath(file_name
).InsertBeforeExtension(
307 chromeos::kSmallWallpaperSuffix
).value();
309 wallpaper_path
= wallpaper_path
.Append(file_name
);
311 sequence_token_
= BrowserThread::GetBlockingPool()->
312 GetNamedSequenceToken(chromeos::kWallpaperSequenceTokenName
);
313 scoped_refptr
<base::SequencedTaskRunner
> task_runner
=
314 BrowserThread::GetBlockingPool()->
315 GetSequencedTaskRunnerWithShutdownBehavior(sequence_token_
,
316 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN
);
318 task_runner
->PostTask(FROM_HERE
,
320 &WallpaperPrivateSetWallpaperIfExistsFunction::
321 ReadFileAndInitiateStartDecode
,
322 this, wallpaper_path
, fallback_path
));
326 void WallpaperPrivateSetWallpaperIfExistsFunction::
327 ReadFileAndInitiateStartDecode(const base::FilePath
& file_path
,
328 const base::FilePath
& fallback_path
) {
329 DCHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread(
332 base::FilePath path
= file_path
;
334 if (!base::PathExists(file_path
))
335 path
= fallback_path
;
337 if (base::PathExists(path
) &&
338 base::ReadFileToString(path
, &data
)) {
339 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
340 base::Bind(&WallpaperPrivateSetWallpaperIfExistsFunction::StartDecode
,
344 std::string error
= base::StringPrintf(
345 "Failed to set wallpaper %s from file system.",
346 path
.BaseName().value().c_str());
347 BrowserThread::PostTask(
348 BrowserThread::UI
, FROM_HERE
,
349 base::Bind(&WallpaperPrivateSetWallpaperIfExistsFunction::OnFileNotExists
,
353 void WallpaperPrivateSetWallpaperIfExistsFunction::OnWallpaperDecoded(
354 const gfx::ImageSkia
& wallpaper
) {
355 // Set unsafe_wallpaper_decoder_ to null since the decoding already finished.
356 unsafe_wallpaper_decoder_
= NULL
;
358 chromeos::WallpaperManager
* wallpaper_manager
=
359 chromeos::WallpaperManager::Get();
360 ash::WallpaperLayout layout
= wallpaper_api_util::GetLayoutEnum(
361 wallpaper_private::ToString(params
->layout
));
363 wallpaper_manager
->SetWallpaperFromImageSkia(wallpaper
, layout
);
365 !chromeos::UserManager::Get()->IsCurrentUserNonCryptohomeDataEphemeral();
366 chromeos::WallpaperInfo info
= {
369 chromeos::User::ONLINE
,
370 base::Time::Now().LocalMidnight()
372 std::string email
= chromeos::UserManager::Get()->GetLoggedInUser()->email();
373 wallpaper_manager
->SetUserWallpaperInfo(email
, info
, is_persistent
);
374 SetResult(base::Value::CreateBooleanValue(true));
378 void WallpaperPrivateSetWallpaperIfExistsFunction::OnFileNotExists(
379 const std::string
& error
) {
380 SetResult(base::Value::CreateBooleanValue(false));
384 WallpaperPrivateSetWallpaperFunction::WallpaperPrivateSetWallpaperFunction() {
387 WallpaperPrivateSetWallpaperFunction::~WallpaperPrivateSetWallpaperFunction() {
390 bool WallpaperPrivateSetWallpaperFunction::RunImpl() {
391 params
= set_wallpaper::Params::Create(*args_
);
392 EXTENSION_FUNCTION_VALIDATE(params
);
394 // Gets email address while at UI thread.
395 email_
= chromeos::UserManager::Get()->GetLoggedInUser()->email();
397 StartDecode(params
->wallpaper
);
402 void WallpaperPrivateSetWallpaperFunction::OnWallpaperDecoded(
403 const gfx::ImageSkia
& wallpaper
) {
404 wallpaper_
= wallpaper
;
405 // Set unsafe_wallpaper_decoder_ to null since the decoding already finished.
406 unsafe_wallpaper_decoder_
= NULL
;
408 sequence_token_
= BrowserThread::GetBlockingPool()->
409 GetNamedSequenceToken(chromeos::kWallpaperSequenceTokenName
);
410 scoped_refptr
<base::SequencedTaskRunner
> task_runner
=
411 BrowserThread::GetBlockingPool()->
412 GetSequencedTaskRunnerWithShutdownBehavior(sequence_token_
,
413 base::SequencedWorkerPool::BLOCK_SHUTDOWN
);
415 task_runner
->PostTask(FROM_HERE
,
416 base::Bind(&WallpaperPrivateSetWallpaperFunction::SaveToFile
, this));
419 void WallpaperPrivateSetWallpaperFunction::SaveToFile() {
420 DCHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread(
422 std::string file_name
= GURL(params
->url
).ExtractFileName();
423 if (SaveData(chrome::DIR_CHROMEOS_WALLPAPERS
, file_name
, params
->wallpaper
)) {
424 wallpaper_
.EnsureRepsForSupportedScales();
425 scoped_ptr
<gfx::ImageSkia
> deep_copy(wallpaper_
.DeepCopy());
426 // ImageSkia is not RefCountedThreadSafe. Use a deep copied ImageSkia if
427 // post to another thread.
428 BrowserThread::PostTask(
429 BrowserThread::UI
, FROM_HERE
,
430 base::Bind(&WallpaperPrivateSetWallpaperFunction::SetDecodedWallpaper
,
431 this, base::Passed(&deep_copy
)));
432 chromeos::UserImage
wallpaper(wallpaper_
);
434 base::FilePath wallpaper_dir
;
435 CHECK(PathService::Get(chrome::DIR_CHROMEOS_WALLPAPERS
, &wallpaper_dir
));
436 base::FilePath file_path
= wallpaper_dir
.Append(
437 file_name
).InsertBeforeExtension(chromeos::kSmallWallpaperSuffix
);
438 if (base::PathExists(file_path
))
440 // Generates and saves small resolution wallpaper. Uses CENTER_CROPPED to
441 // maintain the aspect ratio after resize.
442 chromeos::WallpaperManager::Get()->ResizeAndSaveWallpaper(
445 ash::WALLPAPER_LAYOUT_CENTER_CROPPED
,
446 ash::kSmallWallpaperMaxWidth
,
447 ash::kSmallWallpaperMaxHeight
);
449 std::string error
= base::StringPrintf(
450 "Failed to create/write wallpaper to %s.", file_name
.c_str());
451 BrowserThread::PostTask(
452 BrowserThread::UI
, FROM_HERE
,
453 base::Bind(&WallpaperPrivateSetWallpaperFunction::OnFailure
,
458 void WallpaperPrivateSetWallpaperFunction::SetDecodedWallpaper(
459 scoped_ptr
<gfx::ImageSkia
> wallpaper
) {
460 chromeos::WallpaperManager
* wallpaper_manager
=
461 chromeos::WallpaperManager::Get();
463 ash::WallpaperLayout layout
= wallpaper_api_util::GetLayoutEnum(
464 wallpaper_private::ToString(params
->layout
));
466 wallpaper_manager
->SetWallpaperFromImageSkia(*wallpaper
.get(), layout
);
468 !chromeos::UserManager::Get()->IsCurrentUserNonCryptohomeDataEphemeral();
469 chromeos::WallpaperInfo info
= {
472 chromeos::User::ONLINE
,
473 base::Time::Now().LocalMidnight()
475 wallpaper_manager
->SetUserWallpaperInfo(email_
, info
, is_persistent
);
479 WallpaperPrivateResetWallpaperFunction::
480 WallpaperPrivateResetWallpaperFunction() {}
482 WallpaperPrivateResetWallpaperFunction::
483 ~WallpaperPrivateResetWallpaperFunction() {}
485 bool WallpaperPrivateResetWallpaperFunction::RunImpl() {
486 chromeos::WallpaperManager
* wallpaper_manager
=
487 chromeos::WallpaperManager::Get();
488 chromeos::UserManager
* user_manager
= chromeos::UserManager::Get();
490 std::string email
= user_manager
->GetLoggedInUser()->email();
491 wallpaper_manager
->RemoveUserWallpaperInfo(email
);
493 chromeos::WallpaperInfo info
= {
495 ash::WALLPAPER_LAYOUT_CENTER
,
496 chromeos::User::DEFAULT
,
497 base::Time::Now().LocalMidnight()
500 !user_manager
->IsCurrentUserNonCryptohomeDataEphemeral();
501 wallpaper_manager
->SetUserWallpaperInfo(email
, info
, is_persistent
);
502 wallpaper_manager
->SetDefaultWallpaper();
506 WallpaperPrivateSetCustomWallpaperFunction::
507 WallpaperPrivateSetCustomWallpaperFunction() {}
509 WallpaperPrivateSetCustomWallpaperFunction::
510 ~WallpaperPrivateSetCustomWallpaperFunction() {}
512 bool WallpaperPrivateSetCustomWallpaperFunction::RunImpl() {
513 params
= set_custom_wallpaper::Params::Create(*args_
);
514 EXTENSION_FUNCTION_VALIDATE(params
);
516 // Gets email address and username hash while at UI thread.
517 email_
= chromeos::UserManager::Get()->GetLoggedInUser()->email();
519 chromeos::UserManager::Get()->GetLoggedInUser()->username_hash();
521 StartDecode(params
->wallpaper
);
526 void WallpaperPrivateSetCustomWallpaperFunction::OnWallpaperDecoded(
527 const gfx::ImageSkia
& wallpaper
) {
528 chromeos::WallpaperManager
* wallpaper_manager
=
529 chromeos::WallpaperManager::Get();
530 chromeos::UserImage::RawImage
raw_image(params
->wallpaper
.begin(),
531 params
->wallpaper
.end());
532 chromeos::UserImage
image(wallpaper
, raw_image
);
533 base::FilePath thumbnail_path
= wallpaper_manager
->GetCustomWallpaperPath(
534 chromeos::kThumbnailWallpaperSubDir
, user_id_hash_
, params
->file_name
);
536 sequence_token_
= BrowserThread::GetBlockingPool()->
537 GetNamedSequenceToken(chromeos::kWallpaperSequenceTokenName
);
538 scoped_refptr
<base::SequencedTaskRunner
> task_runner
=
539 BrowserThread::GetBlockingPool()->
540 GetSequencedTaskRunnerWithShutdownBehavior(sequence_token_
,
541 base::SequencedWorkerPool::BLOCK_SHUTDOWN
);
543 ash::WallpaperLayout layout
= wallpaper_api_util::GetLayoutEnum(
544 wallpaper_private::ToString(params
->layout
));
546 wallpaper_manager
->SetCustomWallpaper(email_
,
550 chromeos::User::CUSTOMIZED
,
552 unsafe_wallpaper_decoder_
= NULL
;
554 if (params
->generate_thumbnail
) {
555 wallpaper
.EnsureRepsForSupportedScales();
556 scoped_ptr
<gfx::ImageSkia
> deep_copy(wallpaper
.DeepCopy());
557 // Generates thumbnail before call api function callback. We can then
558 // request thumbnail in the javascript callback.
559 task_runner
->PostTask(FROM_HERE
,
561 &WallpaperPrivateSetCustomWallpaperFunction::GenerateThumbnail
,
562 this, thumbnail_path
, base::Passed(&deep_copy
)));
568 void WallpaperPrivateSetCustomWallpaperFunction::GenerateThumbnail(
569 const base::FilePath
& thumbnail_path
, scoped_ptr
<gfx::ImageSkia
> image
) {
570 DCHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread(
572 chromeos::UserImage
wallpaper(*image
.get());
573 if (!base::PathExists(thumbnail_path
.DirName()))
574 base::CreateDirectory(thumbnail_path
.DirName());
576 scoped_refptr
<base::RefCountedBytes
> data
;
577 chromeos::WallpaperManager::Get()->ResizeWallpaper(
579 ash::WALLPAPER_LAYOUT_STRETCH
,
580 ash::kWallpaperThumbnailWidth
,
581 ash::kWallpaperThumbnailHeight
,
583 BrowserThread::PostTask(
584 BrowserThread::UI
, FROM_HERE
,
586 &WallpaperPrivateSetCustomWallpaperFunction::ThumbnailGenerated
,
590 void WallpaperPrivateSetCustomWallpaperFunction::ThumbnailGenerated(
591 base::RefCountedBytes
* data
) {
592 BinaryValue
* result
= BinaryValue::CreateWithCopiedBuffer(
593 reinterpret_cast<const char*>(data
->front()), data
->size());
598 WallpaperPrivateSetCustomWallpaperLayoutFunction::
599 WallpaperPrivateSetCustomWallpaperLayoutFunction() {}
601 WallpaperPrivateSetCustomWallpaperLayoutFunction::
602 ~WallpaperPrivateSetCustomWallpaperLayoutFunction() {}
604 bool WallpaperPrivateSetCustomWallpaperLayoutFunction::RunImpl() {
605 scoped_ptr
<set_custom_wallpaper_layout::Params
> params(
606 set_custom_wallpaper_layout::Params::Create(*args_
));
607 EXTENSION_FUNCTION_VALIDATE(params
);
609 chromeos::WallpaperManager
* wallpaper_manager
=
610 chromeos::WallpaperManager::Get();
611 chromeos::WallpaperInfo info
;
612 wallpaper_manager
->GetLoggedInUserWallpaperInfo(&info
);
613 if (info
.type
!= chromeos::User::CUSTOMIZED
) {
614 SetError("Only custom wallpaper can change layout.");
618 info
.layout
= wallpaper_api_util::GetLayoutEnum(
619 wallpaper_private::ToString(params
->layout
));
621 std::string email
= chromeos::UserManager::Get()->GetLoggedInUser()->email();
623 !chromeos::UserManager::Get()->IsCurrentUserNonCryptohomeDataEphemeral();
624 wallpaper_manager
->SetUserWallpaperInfo(email
, info
, is_persistent
);
625 wallpaper_manager
->UpdateWallpaper();
628 // Gets email address while at UI thread.
632 WallpaperPrivateMinimizeInactiveWindowsFunction::
633 WallpaperPrivateMinimizeInactiveWindowsFunction() {
636 WallpaperPrivateMinimizeInactiveWindowsFunction::
637 ~WallpaperPrivateMinimizeInactiveWindowsFunction() {
640 bool WallpaperPrivateMinimizeInactiveWindowsFunction::RunImpl() {
641 WindowStateManager::MinimizeInactiveWindows(
642 chromeos::UserManager::Get()->GetActiveUser()->username_hash());
646 WallpaperPrivateRestoreMinimizedWindowsFunction::
647 WallpaperPrivateRestoreMinimizedWindowsFunction() {
650 WallpaperPrivateRestoreMinimizedWindowsFunction::
651 ~WallpaperPrivateRestoreMinimizedWindowsFunction() {
654 bool WallpaperPrivateRestoreMinimizedWindowsFunction::RunImpl() {
655 WindowStateManager::RestoreWindows(
656 chromeos::UserManager::Get()->GetActiveUser()->username_hash());
660 WallpaperPrivateGetThumbnailFunction::WallpaperPrivateGetThumbnailFunction() {
663 WallpaperPrivateGetThumbnailFunction::~WallpaperPrivateGetThumbnailFunction() {
666 bool WallpaperPrivateGetThumbnailFunction::RunImpl() {
667 scoped_ptr
<get_thumbnail::Params
> params(
668 get_thumbnail::Params::Create(*args_
));
669 EXTENSION_FUNCTION_VALIDATE(params
);
671 base::FilePath thumbnail_path
;
672 std::string email
= chromeos::UserManager::Get()->GetLoggedInUser()->email();
673 if (params
->source
== get_thumbnail::Params::SOURCE_ONLINE
) {
674 std::string file_name
= GURL(params
->url_or_file
).ExtractFileName();
675 CHECK(PathService::Get(chrome::DIR_CHROMEOS_WALLPAPER_THUMBNAILS
,
677 thumbnail_path
= thumbnail_path
.Append(file_name
);
679 if (!IsOEMDefaultWallpaper()) {
680 SetError("No OEM wallpaper.");
685 // TODO(bshe): Small resolution wallpaper is used here as wallpaper
686 // thumbnail. We should either resize it or include a wallpaper thumbnail in
687 // addition to large and small wallpaper resolutions.
688 thumbnail_path
= CommandLine::ForCurrentProcess()->GetSwitchValuePath(
689 ash::switches::kAshDefaultWallpaperSmall
);
692 sequence_token_
= BrowserThread::GetBlockingPool()->
693 GetNamedSequenceToken(chromeos::kWallpaperSequenceTokenName
);
694 scoped_refptr
<base::SequencedTaskRunner
> task_runner
=
695 BrowserThread::GetBlockingPool()->
696 GetSequencedTaskRunnerWithShutdownBehavior(sequence_token_
,
697 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN
);
699 task_runner
->PostTask(FROM_HERE
,
700 base::Bind(&WallpaperPrivateGetThumbnailFunction::Get
, this,
705 void WallpaperPrivateGetThumbnailFunction::Failure(
706 const std::string
& file_name
) {
707 SetError(base::StringPrintf("Failed to access wallpaper thumbnails for %s.",
712 void WallpaperPrivateGetThumbnailFunction::FileNotLoaded() {
716 void WallpaperPrivateGetThumbnailFunction::FileLoaded(
717 const std::string
& data
) {
718 BinaryValue
* thumbnail
= BinaryValue::CreateWithCopiedBuffer(data
.c_str(),
720 SetResult(thumbnail
);
724 void WallpaperPrivateGetThumbnailFunction::Get(const base::FilePath
& path
) {
725 DCHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread(
728 if (GetData(path
, &data
)) {
730 BrowserThread::PostTask(
731 BrowserThread::UI
, FROM_HERE
,
732 base::Bind(&WallpaperPrivateGetThumbnailFunction::FileNotLoaded
, this));
734 BrowserThread::PostTask(
735 BrowserThread::UI
, FROM_HERE
,
736 base::Bind(&WallpaperPrivateGetThumbnailFunction::FileLoaded
, this,
740 BrowserThread::PostTask(
741 BrowserThread::UI
, FROM_HERE
,
742 base::Bind(&WallpaperPrivateGetThumbnailFunction::Failure
, this,
743 path
.BaseName().value()));
747 WallpaperPrivateSaveThumbnailFunction::WallpaperPrivateSaveThumbnailFunction() {
750 WallpaperPrivateSaveThumbnailFunction::
751 ~WallpaperPrivateSaveThumbnailFunction() {}
753 bool WallpaperPrivateSaveThumbnailFunction::RunImpl() {
754 scoped_ptr
<save_thumbnail::Params
> params(
755 save_thumbnail::Params::Create(*args_
));
756 EXTENSION_FUNCTION_VALIDATE(params
);
758 sequence_token_
= BrowserThread::GetBlockingPool()->
759 GetNamedSequenceToken(chromeos::kWallpaperSequenceTokenName
);
760 scoped_refptr
<base::SequencedTaskRunner
> task_runner
=
761 BrowserThread::GetBlockingPool()->
762 GetSequencedTaskRunnerWithShutdownBehavior(sequence_token_
,
763 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN
);
765 task_runner
->PostTask(FROM_HERE
,
766 base::Bind(&WallpaperPrivateSaveThumbnailFunction::Save
,
767 this, params
->data
, GURL(params
->url
).ExtractFileName()));
771 void WallpaperPrivateSaveThumbnailFunction::Failure(
772 const std::string
& file_name
) {
773 SetError(base::StringPrintf("Failed to create/write thumbnail of %s.",
778 void WallpaperPrivateSaveThumbnailFunction::Success() {
782 void WallpaperPrivateSaveThumbnailFunction::Save(const std::string
& data
,
783 const std::string
& file_name
) {
784 DCHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread(
786 if (SaveData(chrome::DIR_CHROMEOS_WALLPAPER_THUMBNAILS
, file_name
, data
)) {
787 BrowserThread::PostTask(
788 BrowserThread::UI
, FROM_HERE
,
789 base::Bind(&WallpaperPrivateSaveThumbnailFunction::Success
, this));
791 BrowserThread::PostTask(
792 BrowserThread::UI
, FROM_HERE
,
793 base::Bind(&WallpaperPrivateSaveThumbnailFunction::Failure
,
798 WallpaperPrivateGetOfflineWallpaperListFunction::
799 WallpaperPrivateGetOfflineWallpaperListFunction() {
802 WallpaperPrivateGetOfflineWallpaperListFunction::
803 ~WallpaperPrivateGetOfflineWallpaperListFunction() {
806 bool WallpaperPrivateGetOfflineWallpaperListFunction::RunImpl() {
807 sequence_token_
= BrowserThread::GetBlockingPool()->
808 GetNamedSequenceToken(chromeos::kWallpaperSequenceTokenName
);
809 scoped_refptr
<base::SequencedTaskRunner
> task_runner
=
810 BrowserThread::GetBlockingPool()->
811 GetSequencedTaskRunnerWithShutdownBehavior(sequence_token_
,
812 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN
);
814 task_runner
->PostTask(FROM_HERE
,
815 base::Bind(&WallpaperPrivateGetOfflineWallpaperListFunction::GetList
,
820 void WallpaperPrivateGetOfflineWallpaperListFunction::GetList() {
821 DCHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread(
823 std::vector
<std::string
> file_list
;
824 base::FilePath wallpaper_dir
;
825 CHECK(PathService::Get(chrome::DIR_CHROMEOS_WALLPAPERS
, &wallpaper_dir
));
826 if (base::DirectoryExists(wallpaper_dir
)) {
827 base::FileEnumerator
files(wallpaper_dir
, false,
828 base::FileEnumerator::FILES
);
829 for (base::FilePath current
= files
.Next(); !current
.empty();
830 current
= files
.Next()) {
831 std::string file_name
= current
.BaseName().RemoveExtension().value();
832 // Do not add file name of small resolution wallpaper to the list.
833 if (!EndsWith(file_name
, chromeos::kSmallWallpaperSuffix
, true))
834 file_list
.push_back(current
.BaseName().value());
837 BrowserThread::PostTask(
838 BrowserThread::UI
, FROM_HERE
,
839 base::Bind(&WallpaperPrivateGetOfflineWallpaperListFunction::OnComplete
,
843 void WallpaperPrivateGetOfflineWallpaperListFunction::OnComplete(
844 const std::vector
<std::string
>& file_list
) {
845 base::ListValue
* results
= new base::ListValue();
846 results
->AppendStrings(file_list
);