- add sources.
[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/scoped_platform_file_closer.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::PlatformFile file = base::CreatePlatformFile(
31       path, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, NULL, NULL);
32   if (file == base::kInvalidPlatformFileValue)
33     return result.Pass();
34   base::ScopedPlatformFileCloser file_closer(&file);
35
36   base::PlatformFileInfo file_info;
37   if (!base::GetPlatformFileInfo(file, &file_info) ||
38       file_info.size > kMaxImageFileSize) {
39     return result.Pass();
40   }
41
42   result.reset(new std::string);
43   result->resize(file_info.size);
44   if (base::ReadPlatformFile(file, 0, string_as_array(result.get()),
45                              file_info.size) != file_info.size) {
46     result.reset();
47   }
48
49   return result.Pass();
50 }
51
52 class ImageDecoderDelegateAdapter : public ImageDecoder::Delegate {
53  public:
54   ImageDecoderDelegateAdapter(
55       scoped_ptr<std::string> data,
56       const fileapi::CopyOrMoveFileValidator::ResultCallback& callback)
57       : data_(data.Pass()),
58         callback_(callback) {
59     DCHECK(data_);
60   }
61
62   const std::string& data() {
63     return *data_;
64   }
65
66   // ImageDecoder::Delegate methods.
67   virtual void OnImageDecoded(const ImageDecoder* /*decoder*/,
68                               const SkBitmap& /*decoded_image*/) OVERRIDE {
69     callback_.Run(base::PLATFORM_FILE_OK);
70     delete this;
71   }
72
73   virtual void OnDecodeImageFailed(const ImageDecoder* /*decoder*/) OVERRIDE {
74     callback_.Run(base::PLATFORM_FILE_ERROR_SECURITY);
75     delete this;
76   }
77
78  private:
79   scoped_ptr<std::string> data_;
80   fileapi::CopyOrMoveFileValidator::ResultCallback callback_;
81
82   DISALLOW_COPY_AND_ASSIGN(ImageDecoderDelegateAdapter);
83 };
84
85 }  // namespace
86
87 SupportedImageTypeValidator::~SupportedImageTypeValidator() {}
88
89 // static
90 bool SupportedImageTypeValidator::SupportsFileType(const base::FilePath& path) {
91   base::FilePath::StringType extension = path.Extension();
92   return extension == FILE_PATH_LITERAL(".bmp") ||
93          extension == FILE_PATH_LITERAL(".gif") ||
94          extension == FILE_PATH_LITERAL(".jfif") ||
95          extension == FILE_PATH_LITERAL(".jpeg") ||
96          extension == FILE_PATH_LITERAL(".jpg") ||
97          extension == FILE_PATH_LITERAL(".pjp") ||
98          extension == FILE_PATH_LITERAL(".pjpeg") ||
99          extension == FILE_PATH_LITERAL(".png") ||
100          extension == FILE_PATH_LITERAL(".webp");
101 }
102
103 void SupportedImageTypeValidator::StartPreWriteValidation(
104     const ResultCallback& result_callback) {
105   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
106   DCHECK(callback_.is_null());
107   callback_ = result_callback;
108
109   BrowserThread::PostTaskAndReplyWithResult(
110       BrowserThread::FILE,
111       FROM_HERE,
112       base::Bind(&ReadOnFileThread, path_),
113       base::Bind(&SupportedImageTypeValidator::OnFileOpen,
114                  weak_factory_.GetWeakPtr()));
115 }
116
117 SupportedImageTypeValidator::SupportedImageTypeValidator(
118     const base::FilePath& path)
119     : path_(path),
120       weak_factory_(this) {
121 }
122
123 void SupportedImageTypeValidator::OnFileOpen(scoped_ptr<std::string> data) {
124   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
125   if (!data.get()) {
126     callback_.Run(base::PLATFORM_FILE_ERROR_SECURITY);
127     return;
128   }
129
130   // |adapter| will delete itself after a completion message is received.
131   ImageDecoderDelegateAdapter* adapter =
132       new ImageDecoderDelegateAdapter(data.Pass(), callback_);
133   decoder_ = new ImageDecoder(adapter, adapter->data(),
134                               ImageDecoder::DEFAULT_CODEC);
135   decoder_->Start(content::BrowserThread::GetMessageLoopProxyForThread(
136       BrowserThread::IO));
137 }