#include "ash/desktop_background/desktop_background_controller.h"
#include "base/file_util.h"
+#include "base/lazy_instance.h"
#include "base/path_service.h"
+#include "base/prefs/pref_service.h"
+#include "base/strings/stringprintf.h"
#include "base/threading/worker_pool.h"
-#include "chrome/browser/chromeos/login/user.h"
-#include "chrome/browser/chromeos/login/user_manager.h"
-#include "chrome/browser/chromeos/login/wallpaper_manager.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h"
+#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_paths.h"
+#include "chrome/common/extensions/extension_constants.h"
+#include "chrome/common/pref_names.h"
+#include "components/user_manager/user.h"
+#include "components/user_manager/user_manager.h"
+#include "net/base/load_flags.h"
+#include "net/http/http_status_code.h"
+#include "net/url_request/url_fetcher.h"
+#include "net/url_request/url_fetcher_delegate.h"
+#include "url/gurl.h"
using base::BinaryValue;
using content::BrowserThread;
+typedef base::Callback<void(bool success, const std::string&)> FetchCallback;
+
namespace set_wallpaper = extensions::api::wallpaper::SetWallpaper;
+namespace {
+
+class WallpaperFetcher : public net::URLFetcherDelegate {
+ public:
+ WallpaperFetcher() {}
+
+ virtual ~WallpaperFetcher() {}
+
+ void FetchWallpaper(const GURL& url, FetchCallback callback) {
+ CancelPreviousFetch();
+ callback_ = callback;
+ url_fetcher_.reset(net::URLFetcher::Create(url,
+ net::URLFetcher::GET,
+ this));
+ url_fetcher_->SetRequestContext(
+ g_browser_process->system_request_context());
+ url_fetcher_->SetLoadFlags(net::LOAD_DISABLE_CACHE);
+ url_fetcher_->Start();
+ }
+
+ private:
+ // URLFetcherDelegate overrides:
+ virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE {
+ DCHECK(url_fetcher_.get() == source);
+
+ bool success = source->GetStatus().is_success() &&
+ source->GetResponseCode() == net::HTTP_OK;
+ std::string response;
+ if (success) {
+ source->GetResponseAsString(&response);
+ } else {
+ response = base::StringPrintf(
+ "Downloading wallpaper %s failed. The response code is %d.",
+ source->GetOriginalURL().ExtractFileName().c_str(),
+ source->GetResponseCode());
+ }
+ url_fetcher_.reset();
+ callback_.Run(success, response);
+ }
+
+ void CancelPreviousFetch() {
+ if (url_fetcher_.get()) {
+ callback_.Run(false, wallpaper_api_util::kCancelWallpaperMessage);
+ url_fetcher_.reset();
+ }
+ }
+
+ scoped_ptr<net::URLFetcher> url_fetcher_;
+ FetchCallback callback_;
+};
+
+base::LazyInstance<WallpaperFetcher> g_wallpaper_fetcher =
+ LAZY_INSTANCE_INITIALIZER;
+
+} // namespace
+
WallpaperSetWallpaperFunction::WallpaperSetWallpaperFunction() {
}
WallpaperSetWallpaperFunction::~WallpaperSetWallpaperFunction() {
}
-bool WallpaperSetWallpaperFunction::RunImpl() {
- params = set_wallpaper::Params::Create(*args_);
- EXTENSION_FUNCTION_VALIDATE(params);
+bool WallpaperSetWallpaperFunction::RunAsync() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ params_ = set_wallpaper::Params::Create(*args_);
+ EXTENSION_FUNCTION_VALIDATE(params_);
// Gets email address and username hash while at UI thread.
- email_ = chromeos::UserManager::Get()->GetLoggedInUser()->email();
+ user_id_ = user_manager::UserManager::Get()->GetLoggedInUser()->email();
user_id_hash_ =
- chromeos::UserManager::Get()->GetLoggedInUser()->username_hash();
-
- StartDecode(*(params->details.wallpaper_data));
+ user_manager::UserManager::Get()->GetLoggedInUser()->username_hash();
+ if (params_->details.wallpaper_data) {
+ StartDecode(*params_->details.wallpaper_data);
+ } else {
+ GURL wallpaper_url(*params_->details.url);
+ if (wallpaper_url.is_valid()) {
+ g_wallpaper_fetcher.Get().FetchWallpaper(
+ wallpaper_url,
+ base::Bind(&WallpaperSetWallpaperFunction::OnWallpaperFetched, this));
+ } else {
+ SetError("URL is invalid.");
+ SendResponse(false);
+ }
+ }
return true;
}
void WallpaperSetWallpaperFunction::OnWallpaperDecoded(
- const gfx::ImageSkia& wallpaper) {
+ const gfx::ImageSkia& image) {
chromeos::WallpaperManager* wallpaper_manager =
chromeos::WallpaperManager::Get();
- chromeos::UserImage::RawImage raw_image(
- params->details.wallpaper_data->begin(),
- params->details.wallpaper_data->end());
- chromeos::UserImage image(wallpaper, raw_image);
base::FilePath thumbnail_path = wallpaper_manager->GetCustomWallpaperPath(
- chromeos::kThumbnailWallpaperSubDir, user_id_hash_, params->details.name);
+ chromeos::kThumbnailWallpaperSubDir,
+ user_id_hash_,
+ params_->details.name);
sequence_token_ = BrowserThread::GetBlockingPool()->
GetNamedSequenceToken(chromeos::kWallpaperSequenceTokenName);
GetSequencedTaskRunnerWithShutdownBehavior(sequence_token_,
base::SequencedWorkerPool::BLOCK_SHUTDOWN);
ash::WallpaperLayout layout = wallpaper_api_util::GetLayoutEnum(
- set_wallpaper::Params::Details::ToString(params->details.layout));
- wallpaper_manager->SetCustomWallpaper(email_,
+ set_wallpaper::Params::Details::ToString(params_->details.layout));
+ bool update_wallpaper =
+ user_id_ == user_manager::UserManager::Get()->GetActiveUser()->email();
+ wallpaper_manager->SetCustomWallpaper(user_id_,
user_id_hash_,
- params->details.name,
+ params_->details.name,
layout,
- chromeos::User::CUSTOMIZED,
- image);
+ user_manager::User::CUSTOMIZED,
+ image,
+ update_wallpaper);
unsafe_wallpaper_decoder_ = NULL;
- if (params->details.thumbnail) {
- wallpaper.EnsureRepsForSupportedScales();
- scoped_ptr<gfx::ImageSkia> deep_copy(wallpaper.DeepCopy());
+ if (params_->details.thumbnail) {
+ image.EnsureRepsForSupportedScales();
+ scoped_ptr<gfx::ImageSkia> deep_copy(image.DeepCopy());
// Generates thumbnail before call api function callback. We can then
// request thumbnail in the javascript callback.
- task_runner->PostTask(FROM_HERE,
- base::Bind(
- &WallpaperSetWallpaperFunction::GenerateThumbnail,
- this, thumbnail_path, base::Passed(&deep_copy)));
+ task_runner->PostTask(
+ FROM_HERE,
+ base::Bind(&WallpaperSetWallpaperFunction::GenerateThumbnail,
+ this,
+ thumbnail_path,
+ base::Passed(deep_copy.Pass())));
} else {
+ // Save current extenion name. It will be displayed in the component
+ // wallpaper picker app. If current extension is the component wallpaper
+ // picker, set an empty string.
+ Profile* profile = Profile::FromBrowserContext(browser_context());
+ if (extension()->id() == extension_misc::kWallpaperManagerId) {
+ profile->GetPrefs()->SetString(prefs::kCurrentWallpaperAppName,
+ std::string());
+ } else {
+ profile->GetPrefs()->SetString(prefs::kCurrentWallpaperAppName,
+ extension()->name());
+ }
SendResponse(true);
}
}
const base::FilePath& thumbnail_path, scoped_ptr<gfx::ImageSkia> image) {
DCHECK(BrowserThread::GetBlockingPool()->IsRunningSequenceOnCurrentThread(
sequence_token_));
- chromeos::UserImage wallpaper(*image.get());
if (!base::PathExists(thumbnail_path.DirName()))
- file_util::CreateDirectory(thumbnail_path.DirName());
+ base::CreateDirectory(thumbnail_path.DirName());
scoped_refptr<base::RefCountedBytes> data;
- chromeos::WallpaperManager::Get()->ResizeWallpaper(
- wallpaper,
+ chromeos::WallpaperManager::Get()->ResizeImage(
+ *image,
ash::WALLPAPER_LAYOUT_STRETCH,
- ash::kWallpaperThumbnailWidth,
- ash::kWallpaperThumbnailHeight,
- &data);
+ chromeos::kWallpaperThumbnailWidth,
+ chromeos::kWallpaperThumbnailHeight,
+ &data,
+ NULL);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(
SetResult(result);
SendResponse(true);
}
+
+void WallpaperSetWallpaperFunction::OnWallpaperFetched(
+ bool success,
+ const std::string& response) {
+ if (success) {
+ params_->details.wallpaper_data.reset(new std::string(response));
+ StartDecode(*params_->details.wallpaper_data);
+ } else {
+ SetError(response);
+ SendResponse(false);
+ }
+}