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