root/chrome/browser/chromeos/extensions/wallpaper_function_base.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. GetLayoutEnum
  2. UnsafeWallpaperDecoder
  3. Start
  4. Cancel
  5. OnImageDecoded
  6. OnDecodeImageFailed
  7. StartDecode
  8. OnCancel
  9. OnFailure

// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/extensions/wallpaper_function_base.h"

#include "base/synchronization/cancellation_flag.h"
#include "chrome/browser/image_decoder.h"
#include "chromeos/login/login_state.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"

using content::BrowserThread;

namespace wallpaper_api_util {
namespace {

// Keeps in sync (same order) with WallpaperLayout enum in header file.
const char* kWallpaperLayoutArrays[] = {
  "CENTER",
  "CENTER_CROPPED",
  "STRETCH",
  "TILE"
};

const int kWallpaperLayoutCount = arraysize(kWallpaperLayoutArrays);

} // namespace

ash::WallpaperLayout GetLayoutEnum(const std::string& layout) {
  for (int i = 0; i < kWallpaperLayoutCount; i++) {
    if (layout.compare(kWallpaperLayoutArrays[i]) == 0)
      return static_cast<ash::WallpaperLayout>(i);
  }
  // Default to use CENTER layout.
  return ash::WALLPAPER_LAYOUT_CENTER;
}

}  // namespace wallpaper_api_util

class WallpaperFunctionBase::UnsafeWallpaperDecoder
    : public ImageDecoder::Delegate {
 public:
  explicit UnsafeWallpaperDecoder(scoped_refptr<WallpaperFunctionBase> function)
      : function_(function) {
  }

  void Start(const std::string& image_data) {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));

    // This function can only be called after user login. It is fine to use
    // unsafe image decoder here. Before user login, a robust jpeg decoder will
    // be used.
    CHECK(chromeos::LoginState::Get()->IsUserLoggedIn());
    unsafe_image_decoder_ = new ImageDecoder(this, image_data,
                                             ImageDecoder::DEFAULT_CODEC);
    scoped_refptr<base::MessageLoopProxy> task_runner =
        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI);
    unsafe_image_decoder_->Start(task_runner);
  }

  void Cancel() {
    cancel_flag_.Set();
  }

  virtual void OnImageDecoded(const ImageDecoder* decoder,
                              const SkBitmap& decoded_image) OVERRIDE {
    // Make the SkBitmap immutable as we won't modify it. This is important
    // because otherwise it gets duplicated during painting, wasting memory.
    SkBitmap immutable(decoded_image);
    immutable.setImmutable();
    gfx::ImageSkia final_image = gfx::ImageSkia::CreateFrom1xBitmap(immutable);
    final_image.MakeThreadSafe();
    if (cancel_flag_.IsSet()) {
      function_->OnCancel();
      delete this;
      return;
    }
    function_->OnWallpaperDecoded(final_image);
    delete this;
  }

  virtual void OnDecodeImageFailed(const ImageDecoder* decoder) OVERRIDE {
    function_->OnFailure(
        l10n_util::GetStringUTF8(IDS_WALLPAPER_MANAGER_INVALID_WALLPAPER));
    delete this;
  }

 private:
  scoped_refptr<WallpaperFunctionBase> function_;
  scoped_refptr<ImageDecoder> unsafe_image_decoder_;
  base::CancellationFlag cancel_flag_;

  DISALLOW_COPY_AND_ASSIGN(UnsafeWallpaperDecoder);
};

WallpaperFunctionBase::UnsafeWallpaperDecoder*
    WallpaperFunctionBase::unsafe_wallpaper_decoder_;

WallpaperFunctionBase::WallpaperFunctionBase() {
}

WallpaperFunctionBase::~WallpaperFunctionBase() {
}

void WallpaperFunctionBase::StartDecode(const std::string& data) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  if (unsafe_wallpaper_decoder_)
    unsafe_wallpaper_decoder_->Cancel();
  unsafe_wallpaper_decoder_ = new UnsafeWallpaperDecoder(this);
  unsafe_wallpaper_decoder_->Start(data);
}

void WallpaperFunctionBase::OnCancel() {
  unsafe_wallpaper_decoder_ = NULL;
  SendResponse(false);
}

void WallpaperFunctionBase::OnFailure(const std::string& error) {
  unsafe_wallpaper_decoder_ = NULL;
  SetError(error);
  SendResponse(false);
}

/* [<][>][^][v][top][bottom][index][help] */