ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / chromeos / extensions / wallpaper_api.cc
blob5eb9af3dcf20b53a175461c4b38e680228cbfa2e
1 // Copyright 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_api.h"
7 #include <string>
8 #include <vector>
10 #include "ash/desktop_background/desktop_background_controller.h"
11 #include "base/files/file_util.h"
12 #include "base/lazy_instance.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/threading/worker_pool.h"
16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/common/chrome_paths.h"
20 #include "chrome/common/extensions/extension_constants.h"
21 #include "chrome/common/pref_names.h"
22 #include "components/user_manager/user.h"
23 #include "components/user_manager/user_manager.h"
24 #include "components/wallpaper/wallpaper_layout.h"
25 #include "net/base/load_flags.h"
26 #include "net/http/http_status_code.h"
27 #include "net/url_request/url_fetcher.h"
28 #include "net/url_request/url_fetcher_delegate.h"
29 #include "url/gurl.h"
31 using base::BinaryValue;
32 using content::BrowserThread;
34 typedef base::Callback<void(bool success, const std::string&)> FetchCallback;
36 namespace set_wallpaper = extensions::api::wallpaper::SetWallpaper;
38 namespace {
40 class WallpaperFetcher : public net::URLFetcherDelegate {
41 public:
42 WallpaperFetcher() {}
44 ~WallpaperFetcher() override {}
46 void FetchWallpaper(const GURL& url, FetchCallback callback) {
47 CancelPreviousFetch();
48 callback_ = callback;
49 url_fetcher_.reset(net::URLFetcher::Create(url,
50 net::URLFetcher::GET,
51 this));
52 url_fetcher_->SetRequestContext(
53 g_browser_process->system_request_context());
54 url_fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE);
55 url_fetcher_->Start();
58 private:
59 // URLFetcherDelegate overrides:
60 void OnURLFetchComplete(const net::URLFetcher* source) override {
61 DCHECK(url_fetcher_.get() == source);
63 bool success = source->GetStatus().is_success() &&
64 source->GetResponseCode() == net::HTTP_OK;
65 std::string response;
66 if (success) {
67 source->GetResponseAsString(&response);
68 } else {
69 response = base::StringPrintf(
70 "Downloading wallpaper %s failed. The response code is %d.",
71 source->GetOriginalURL().ExtractFileName().c_str(),
72 source->GetResponseCode());
74 url_fetcher_.reset();
75 callback_.Run(success, response);
78 void CancelPreviousFetch() {
79 if (url_fetcher_.get()) {
80 callback_.Run(false, wallpaper_api_util::kCancelWallpaperMessage);
81 url_fetcher_.reset();
85 scoped_ptr<net::URLFetcher> url_fetcher_;
86 FetchCallback callback_;
89 base::LazyInstance<WallpaperFetcher> g_wallpaper_fetcher =
90 LAZY_INSTANCE_INITIALIZER;
92 } // namespace
94 WallpaperSetWallpaperFunction::WallpaperSetWallpaperFunction() {
97 WallpaperSetWallpaperFunction::~WallpaperSetWallpaperFunction() {
100 bool WallpaperSetWallpaperFunction::RunAsync() {
101 DCHECK_CURRENTLY_ON(BrowserThread::UI);
102 params_ = set_wallpaper::Params::Create(*args_);
103 EXTENSION_FUNCTION_VALIDATE(params_);
105 // Gets email address and username hash while at UI thread.
106 user_id_ = user_manager::UserManager::Get()->GetLoggedInUser()->email();
107 user_id_hash_ =
108 user_manager::UserManager::Get()->GetLoggedInUser()->username_hash();
110 if (params_->details.data) {
111 StartDecode(*params_->details.data);
112 } else {
113 GURL wallpaper_url(*params_->details.url);
114 if (wallpaper_url.is_valid()) {
115 g_wallpaper_fetcher.Get().FetchWallpaper(
116 wallpaper_url,
117 base::Bind(&WallpaperSetWallpaperFunction::OnWallpaperFetched, this));
118 } else {
119 SetError("URL is invalid.");
120 SendResponse(false);
123 return true;
126 void WallpaperSetWallpaperFunction::OnWallpaperDecoded(
127 const gfx::ImageSkia& image) {
128 chromeos::WallpaperManager* wallpaper_manager =
129 chromeos::WallpaperManager::Get();
130 base::FilePath thumbnail_path = wallpaper_manager->GetCustomWallpaperPath(
131 wallpaper::kThumbnailWallpaperSubDir, user_id_hash_,
132 params_->details.filename);
134 sequence_token_ = BrowserThread::GetBlockingPool()->GetNamedSequenceToken(
135 wallpaper::kWallpaperSequenceTokenName);
136 scoped_refptr<base::SequencedTaskRunner> task_runner =
137 BrowserThread::GetBlockingPool()->
138 GetSequencedTaskRunnerWithShutdownBehavior(sequence_token_,
139 base::SequencedWorkerPool::BLOCK_SHUTDOWN);
140 wallpaper::WallpaperLayout layout = wallpaper_api_util::GetLayoutEnum(
141 set_wallpaper::Params::Details::ToString(params_->details.layout));
142 bool update_wallpaper =
143 user_id_ == user_manager::UserManager::Get()->GetActiveUser()->email();
144 wallpaper_manager->SetCustomWallpaper(user_id_,
145 user_id_hash_,
146 params_->details.filename,
147 layout,
148 user_manager::User::CUSTOMIZED,
149 image,
150 update_wallpaper);
151 unsafe_wallpaper_decoder_ = NULL;
153 if (params_->details.thumbnail) {
154 image.EnsureRepsForSupportedScales();
155 scoped_ptr<gfx::ImageSkia> deep_copy(image.DeepCopy());
156 // Generates thumbnail before call api function callback. We can then
157 // request thumbnail in the javascript callback.
158 task_runner->PostTask(
159 FROM_HERE,
160 base::Bind(&WallpaperSetWallpaperFunction::GenerateThumbnail,
161 this,
162 thumbnail_path,
163 base::Passed(deep_copy.Pass())));
164 } else {
165 // Save current extenion name. It will be displayed in the component
166 // wallpaper picker app. If current extension is the component wallpaper
167 // picker, set an empty string.
168 Profile* profile = Profile::FromBrowserContext(browser_context());
169 if (extension()->id() == extension_misc::kWallpaperManagerId) {
170 profile->GetPrefs()->SetString(prefs::kCurrentWallpaperAppName,
171 std::string());
172 } else {
173 profile->GetPrefs()->SetString(prefs::kCurrentWallpaperAppName,
174 extension()->name());
176 SendResponse(true);
180 void WallpaperSetWallpaperFunction::GenerateThumbnail(
181 const base::FilePath& thumbnail_path, scoped_ptr<gfx::ImageSkia> image) {
182 DCHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread(
183 sequence_token_));
184 if (!base::PathExists(thumbnail_path.DirName()))
185 base::CreateDirectory(thumbnail_path.DirName());
187 scoped_refptr<base::RefCountedBytes> data;
188 chromeos::WallpaperManager::Get()->ResizeImage(
189 *image, wallpaper::WALLPAPER_LAYOUT_STRETCH,
190 wallpaper::kWallpaperThumbnailWidth, wallpaper::kWallpaperThumbnailHeight,
191 &data, NULL);
192 BrowserThread::PostTask(
193 BrowserThread::UI, FROM_HERE,
194 base::Bind(
195 &WallpaperSetWallpaperFunction::ThumbnailGenerated,
196 this, data));
199 void WallpaperSetWallpaperFunction::ThumbnailGenerated(
200 base::RefCountedBytes* data) {
201 BinaryValue* result = BinaryValue::CreateWithCopiedBuffer(
202 reinterpret_cast<const char*>(data->front()), data->size());
203 SetResult(result);
204 SendResponse(true);
207 void WallpaperSetWallpaperFunction::OnWallpaperFetched(
208 bool success,
209 const std::string& response) {
210 if (success) {
211 params_->details.data.reset(
212 new std::vector<char>(response.begin(), response.end()));
213 StartDecode(*params_->details.data);
214 } else {
215 SetError(response);
216 SendResponse(false);