- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / icon_loader_chromeos.cc
1 // Copyright (c) 2012 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/icon_loader.h"
6
7 #include <map>
8 #include <string>
9 #include <utility>
10
11 #include "base/bind.h"
12 #include "base/files/file_path.h"
13 #include "base/lazy_instance.h"
14 #include "base/memory/ref_counted_memory.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/strings/string_util.h"
17 #include "chrome/browser/icon_loader.h"
18 #include "grit/theme_resources.h"
19 #include "third_party/skia/include/core/SkBitmap.h"
20 #include "ui/base/layout.h"
21 #include "ui/base/resource/resource_bundle.h"
22 #include "ui/gfx/canvas.h"
23 #include "ui/gfx/codec/png_codec.h"
24 #include "ui/gfx/image/image.h"
25 #include "ui/gfx/image/image_skia.h"
26 #include "ui/gfx/image/image_skia_operations.h"
27
28 namespace {
29
30 // Used with GenerateImageWithSize() to indicate that the image shouldn't be
31 // resized.
32 const int kDoNotResize = -1;
33
34 struct IdrBySize {
35   int idr_small;
36   int idr_normal;
37   int idr_large;
38 };
39
40 // Performs mapping of <file extension, icon size> to icon resource IDs.
41 class IconMapper {
42  public:
43   IconMapper();
44
45   // Lookup icon resource ID for a given filename |extension| and
46   // |icon_size|. Defaults to generic icons if there are no icons for the given
47   // extension.
48   int Lookup(const std::string& extension, IconLoader::IconSize icon_size);
49
50  private:
51   typedef std::map<std::string, IdrBySize> ExtensionIconMap;
52
53   ExtensionIconMap extension_icon_map_;
54 };
55
56 const IdrBySize kAudioIdrs = {
57   IDR_FILE_MANAGER_IMG_FILETYPE_AUDIO,
58   IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_AUDIO,
59   IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_AUDIO
60 };
61 const IdrBySize kGenericIdrs = {
62   IDR_FILE_MANAGER_IMG_FILETYPE_GENERIC,
63   IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_GENERIC,
64   IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_GENERIC
65 };
66 const IdrBySize kImageIdrs = {
67   IDR_FILE_MANAGER_IMG_FILETYPE_IMAGE,
68   IDR_FILE_MANAGER_IMG_FILETYPE_IMAGE,
69   IDR_FILE_MANAGER_IMG_FILETYPE_IMAGE
70 };
71 #if defined(USE_PROPRIETARY_CODECS)
72 const IdrBySize kPdfIdrs = {
73   IDR_FILE_MANAGER_IMG_FILETYPE_PDF,
74   IDR_FILE_MANAGER_IMG_FILETYPE_PDF,
75   IDR_FILE_MANAGER_IMG_FILETYPE_PDF
76 };
77 #endif
78 const IdrBySize kVideoIdrs = {
79   IDR_FILE_MANAGER_IMG_FILETYPE_VIDEO,
80   IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_VIDEO,
81   IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_VIDEO
82 };
83
84 IconMapper::IconMapper() {
85   // The code below should match translation in
86   // chrome/browser/resources/file_manager/js/file_manager.js
87   // chrome/browser/resources/file_manager/css/file_manager.css
88   // 'audio': /\.(mp3|m4a|oga|ogg|wav)$/i,
89   // 'html': /\.(html?)$/i,
90   // 'image': /\.(bmp|gif|jpe?g|ico|png|webp)$/i,
91   // 'pdf' : /\.(pdf)$/i,
92   // 'text': /\.(pod|rst|txt|log)$/i,
93   // 'video': /\.(mov|mp4|m4v|mpe?g4?|ogm|ogv|ogx|webm)$/i
94
95   const ExtensionIconMap::value_type kExtensionIdrBySizeData[] = {
96 #if defined(USE_PROPRIETARY_CODECS)
97     std::make_pair(".m4a", kAudioIdrs),
98     std::make_pair(".mp3", kAudioIdrs),
99     std::make_pair(".pdf", kPdfIdrs),
100     std::make_pair(".3gp", kVideoIdrs),
101     std::make_pair(".avi", kVideoIdrs),
102     std::make_pair(".m4v", kVideoIdrs),
103     std::make_pair(".mov", kVideoIdrs),
104     std::make_pair(".mp4", kVideoIdrs),
105     std::make_pair(".mpeg", kVideoIdrs),
106     std::make_pair(".mpg", kVideoIdrs),
107     std::make_pair(".mpeg4", kVideoIdrs),
108     std::make_pair(".mpg4", kVideoIdrs),
109 #endif
110     std::make_pair(".flac", kAudioIdrs),
111     std::make_pair(".oga", kAudioIdrs),
112     std::make_pair(".ogg", kAudioIdrs),
113     std::make_pair(".wav", kAudioIdrs),
114     std::make_pair(".bmp", kImageIdrs),
115     std::make_pair(".gif", kImageIdrs),
116     std::make_pair(".ico", kImageIdrs),
117     std::make_pair(".jpeg", kImageIdrs),
118     std::make_pair(".jpg", kImageIdrs),
119     std::make_pair(".png", kImageIdrs),
120     std::make_pair(".webp", kImageIdrs),
121     std::make_pair(".ogm", kVideoIdrs),
122     std::make_pair(".ogv", kVideoIdrs),
123     std::make_pair(".ogx", kVideoIdrs),
124     std::make_pair(".webm", kVideoIdrs),
125   };
126
127   const size_t kESize = arraysize(kExtensionIdrBySizeData);
128   ExtensionIconMap source(&kExtensionIdrBySizeData[0],
129                           &kExtensionIdrBySizeData[kESize]);
130   extension_icon_map_.swap(source);
131 }
132
133 int IconMapper::Lookup(const std::string& extension,
134                        IconLoader::IconSize icon_size) {
135   DCHECK(icon_size == IconLoader::SMALL ||
136          icon_size == IconLoader::NORMAL ||
137          icon_size == IconLoader::LARGE);
138   ExtensionIconMap::const_iterator it = extension_icon_map_.find(extension);
139   const IdrBySize& idrbysize =
140       ((it == extension_icon_map_.end()) ? kGenericIdrs : it->second);
141   int idr = -1;
142   switch (icon_size) {
143     case IconLoader::SMALL:  idr = idrbysize.idr_small;  break;
144     case IconLoader::NORMAL: idr = idrbysize.idr_normal; break;
145     case IconLoader::LARGE:  idr = idrbysize.idr_large;  break;
146     case IconLoader::ALL:
147     default:
148       NOTREACHED();
149   }
150   return idr;
151 }
152
153 // Returns a copy of |source| that is |dip_size| in width and height. If
154 // |dip_size| is |kDoNotResize|, returns an unmodified copy of |source|.
155 // |source| must be a square image (width == height).
156 gfx::ImageSkia ResizeImage(const gfx::ImageSkia& source, int dip_size) {
157   DCHECK(!source.isNull());
158   DCHECK(source.width() == source.height());
159
160   if (dip_size == kDoNotResize || source.width() == dip_size)
161     return source;
162
163   return gfx::ImageSkiaOperations::CreateResizedImage(source,
164       skia::ImageOperations::RESIZE_BEST, gfx::Size(dip_size, dip_size));
165 }
166
167 int IconSizeToDIPSize(IconLoader::IconSize size) {
168   switch (size) {
169     case IconLoader::SMALL:  return 16;
170     case IconLoader::NORMAL: return 32;
171     case IconLoader::LARGE:  // fallthrough
172       // On ChromeOS, we consider LARGE to mean "the largest image we have."
173       // Since we have already chosen the largest applicable image resource, we
174       // return the image as-is.
175     case IconLoader::ALL:    // fallthrough
176     default:
177       return kDoNotResize;
178   }
179 }
180
181 }  // namespace
182
183 // static
184 IconGroupID IconLoader::ReadGroupIDFromFilepath(
185     const base::FilePath& filepath) {
186   return StringToLowerASCII(filepath.Extension());
187 }
188
189 bool IconLoader::IsIconMutableFromFilepath(const base::FilePath&) {
190   return false;
191 }
192
193 void IconLoader::ReadIcon() {
194   static base::LazyInstance<IconMapper>::Leaky icon_mapper =
195       LAZY_INSTANCE_INITIALIZER;
196   int idr = icon_mapper.Get().Lookup(group_, icon_size_);
197   ResourceBundle& rb = ResourceBundle::GetSharedInstance();
198   gfx::ImageSkia image_skia(ResizeImage(*(rb.GetImageNamed(idr)).ToImageSkia(),
199                                         IconSizeToDIPSize(icon_size_)));
200   image_skia.MakeThreadSafe();
201   image_.reset(new gfx::Image(image_skia));
202   target_message_loop_->PostTask(
203       FROM_HERE, base::Bind(&IconLoader::NotifyDelegate, this));
204 }