Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / media_galleries / fileapi / supported_image_type_validator.cc
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/media_galleries/fileapi/supported_image_type_validator.h"
6
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/files/file.h"
10 #include "base/location.h"
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/stl_util.h"
15 #include "base/threading/thread_restrictions.h"
16 #include "chrome/browser/image_decoder.h"
17 #include "content/public/browser/browser_thread.h"
18
19 using content::BrowserThread;
20
21 namespace {
22
23 // Arbitrary limit to sanity check the file size.
24 const int kMaxImageFileSize = 50*1014*1024;
25
26 scoped_ptr<std::string> ReadOnFileThread(const base::FilePath& path) {
27   base::ThreadRestrictions::AssertIOAllowed();
28   scoped_ptr<std::string> result;
29
30   base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
31   if (!file.IsValid())
32     return result.Pass();
33
34   base::File::Info file_info;
35   if (!file.GetInfo(&file_info) ||
36       file_info.size > kMaxImageFileSize) {
37     return result.Pass();
38   }
39
40   result.reset(new std::string);
41   result->resize(file_info.size);
42   if (file.Read(0, string_as_array(result.get()), file_info.size) !=
43       file_info.size) {
44     result.reset();
45   }
46
47   return result.Pass();
48 }
49
50 class ImageDecoderDelegateAdapter : public ImageDecoder::Delegate {
51  public:
52   ImageDecoderDelegateAdapter(
53       scoped_ptr<std::string> data,
54       const storage::CopyOrMoveFileValidator::ResultCallback& callback)
55       : data_(data.Pass()), callback_(callback) {
56     DCHECK(data_);
57   }
58
59   const std::string& data() {
60     return *data_;
61   }
62
63   // ImageDecoder::Delegate methods.
64   virtual void OnImageDecoded(const ImageDecoder* /*decoder*/,
65                               const SkBitmap& /*decoded_image*/) OVERRIDE {
66     callback_.Run(base::File::FILE_OK);
67     delete this;
68   }
69
70   virtual void OnDecodeImageFailed(const ImageDecoder* /*decoder*/) OVERRIDE {
71     callback_.Run(base::File::FILE_ERROR_SECURITY);
72     delete this;
73   }
74
75  private:
76   scoped_ptr<std::string> data_;
77   storage::CopyOrMoveFileValidator::ResultCallback callback_;
78
79   DISALLOW_COPY_AND_ASSIGN(ImageDecoderDelegateAdapter);
80 };
81
82 }  // namespace
83
84 SupportedImageTypeValidator::~SupportedImageTypeValidator() {}
85
86 // static
87 bool SupportedImageTypeValidator::SupportsFileType(const base::FilePath& path) {
88   base::FilePath::StringType extension = path.Extension();
89   return extension == FILE_PATH_LITERAL(".bmp") ||
90          extension == FILE_PATH_LITERAL(".gif") ||
91          extension == FILE_PATH_LITERAL(".jfif") ||
92          extension == FILE_PATH_LITERAL(".jpeg") ||
93          extension == FILE_PATH_LITERAL(".jpg") ||
94          extension == FILE_PATH_LITERAL(".pjp") ||
95          extension == FILE_PATH_LITERAL(".pjpeg") ||
96          extension == FILE_PATH_LITERAL(".png") ||
97          extension == FILE_PATH_LITERAL(".webp");
98 }
99
100 void SupportedImageTypeValidator::StartPreWriteValidation(
101     const ResultCallback& result_callback) {
102   DCHECK_CURRENTLY_ON(BrowserThread::IO);
103   DCHECK(callback_.is_null());
104   callback_ = result_callback;
105
106   BrowserThread::PostTaskAndReplyWithResult(
107       BrowserThread::FILE,
108       FROM_HERE,
109       base::Bind(&ReadOnFileThread, path_),
110       base::Bind(&SupportedImageTypeValidator::OnFileOpen,
111                  weak_factory_.GetWeakPtr()));
112 }
113
114 SupportedImageTypeValidator::SupportedImageTypeValidator(
115     const base::FilePath& path)
116     : path_(path),
117       weak_factory_(this) {
118 }
119
120 void SupportedImageTypeValidator::OnFileOpen(scoped_ptr<std::string> data) {
121   DCHECK_CURRENTLY_ON(BrowserThread::IO);
122   if (!data.get()) {
123     callback_.Run(base::File::FILE_ERROR_SECURITY);
124     return;
125   }
126
127   // |adapter| will delete itself after a completion message is received.
128   ImageDecoderDelegateAdapter* adapter =
129       new ImageDecoderDelegateAdapter(data.Pass(), callback_);
130   decoder_ = new ImageDecoder(adapter, adapter->data(),
131                               ImageDecoder::DEFAULT_CODEC);
132   decoder_->Start(content::BrowserThread::GetMessageLoopProxyForThread(
133       BrowserThread::IO));
134 }