1d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// found in the LICENSE file. 4d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 5d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chrome/browser/chromeos/extensions/wallpaper_function_base.h" 6d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 7d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/synchronization/cancellation_flag.h" 8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chrome/browser/image_decoder.h" 96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/grit/generated_resources.h" 10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "chromeos/login/login_state.h" 11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using content::BrowserThread; 14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace wallpaper_api_util { 16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace { 17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Keeps in sync (same order) with WallpaperLayout enum in header file. 19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)const char* kWallpaperLayoutArrays[] = { 20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "CENTER", 21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "CENTER_CROPPED", 22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "STRETCH", 23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "TILE" 24d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}; 25d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 26d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)const int kWallpaperLayoutCount = arraysize(kWallpaperLayoutArrays); 27d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} // namespace 29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)const char kCancelWallpaperMessage[] = "Set wallpaper was canceled."; 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)ash::WallpaperLayout GetLayoutEnum(const std::string& layout) { 33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for (int i = 0; i < kWallpaperLayoutCount; i++) { 34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (layout.compare(kWallpaperLayoutArrays[i]) == 0) 35d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return static_cast<ash::WallpaperLayout>(i); 36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Default to use CENTER layout. 38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return ash::WALLPAPER_LAYOUT_CENTER; 39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} // namespace wallpaper_api_util 42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class WallpaperFunctionBase::UnsafeWallpaperDecoder 44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : public ImageDecoder::Delegate { 45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public: 46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) explicit UnsafeWallpaperDecoder(scoped_refptr<WallpaperFunctionBase> function) 47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) : function_(function) { 48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 50d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void Start(const std::string& image_data) { 51d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 52d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 53d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // This function can only be called after user login. It is fine to use 54d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // unsafe image decoder here. Before user login, a robust jpeg decoder will 55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // be used. 56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) CHECK(chromeos::LoginState::Get()->IsUserLoggedIn()); 57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) unsafe_image_decoder_ = new ImageDecoder(this, image_data, 58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ImageDecoder::DEFAULT_CODEC); 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci unsafe_image_decoder_->set_shrink_to_fit(true); 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 61d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_refptr<base::MessageLoopProxy> task_runner = 62d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); 63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) unsafe_image_decoder_->Start(task_runner); 64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) void Cancel() { 67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) cancel_flag_.Set(); 68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void OnImageDecoded(const ImageDecoder* decoder, 71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) const SkBitmap& decoded_image) OVERRIDE { 72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Make the SkBitmap immutable as we won't modify it. This is important 73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // because otherwise it gets duplicated during painting, wasting memory. 74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) SkBitmap immutable(decoded_image); 75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) immutable.setImmutable(); 76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) gfx::ImageSkia final_image = gfx::ImageSkia::CreateFrom1xBitmap(immutable); 77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) final_image.MakeThreadSafe(); 78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (cancel_flag_.IsSet()) { 79d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) function_->OnCancel(); 80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) delete this; 81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return; 82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 83d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) function_->OnWallpaperDecoded(final_image); 84d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) delete this; 85d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 86d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 87d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) virtual void OnDecodeImageFailed(const ImageDecoder* decoder) OVERRIDE { 88d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) function_->OnFailure( 89d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) l10n_util::GetStringUTF8(IDS_WALLPAPER_MANAGER_INVALID_WALLPAPER)); 90d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) delete this; 91d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private: 94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_refptr<WallpaperFunctionBase> function_; 95d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_refptr<ImageDecoder> unsafe_image_decoder_; 96d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) base::CancellationFlag cancel_flag_; 97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(UnsafeWallpaperDecoder); 99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}; 100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)WallpaperFunctionBase::UnsafeWallpaperDecoder* 102d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) WallpaperFunctionBase::unsafe_wallpaper_decoder_; 103d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 104d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)WallpaperFunctionBase::WallpaperFunctionBase() { 105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 106d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 107d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)WallpaperFunctionBase::~WallpaperFunctionBase() { 108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 109d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 110d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void WallpaperFunctionBase::StartDecode(const std::string& data) { 111d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 112d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) if (unsafe_wallpaper_decoder_) 113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) unsafe_wallpaper_decoder_->Cancel(); 114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) unsafe_wallpaper_decoder_ = new UnsafeWallpaperDecoder(this); 115d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) unsafe_wallpaper_decoder_->Start(data); 116d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 117d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 118d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void WallpaperFunctionBase::OnCancel() { 119d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) unsafe_wallpaper_decoder_ = NULL; 120cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SetError(wallpaper_api_util::kCancelWallpaperMessage); 121d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) SendResponse(false); 122d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 123d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 124d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void WallpaperFunctionBase::OnFailure(const std::string& error) { 125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) unsafe_wallpaper_decoder_ = NULL; 126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) SetError(error); 127d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) SendResponse(false); 128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 129