• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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/ui/webui/fileicon_source.h"
6 
7 #include "base/callback.h"
8 #include "base/file_path.h"
9 #include "base/memory/ref_counted_memory.h"
10 #include "base/utf_string_conversions.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/common/time_format.h"
13 #include "grit/generated_resources.h"
14 #include "net/base/escape.h"
15 #include "third_party/skia/include/core/SkBitmap.h"
16 #include "ui/gfx/codec/png_codec.h"
17 #include "ui/gfx/image.h"
18 
19 // The path used in internal URLs to file icon data.
20 static const char kFileIconPath[] = "fileicon";
21 
FileIconSource()22 FileIconSource::FileIconSource()
23     : DataSource(kFileIconPath, MessageLoop::current()) {}
24 
~FileIconSource()25 FileIconSource::~FileIconSource() {
26   cancelable_consumer_.CancelAllRequests();
27 }
28 
StartDataRequest(const std::string & path,bool is_incognito,int request_id)29 void FileIconSource::StartDataRequest(const std::string& path,
30                                       bool is_incognito,
31                                       int request_id) {
32   std::string escaped_path = UnescapeURLComponent(path, UnescapeRule::SPACES);
33 #if defined(OS_WIN)
34   // The path we receive has the wrong slashes and escaping for what we need;
35   // this only appears to matter for getting icons from .exe files.
36   std::replace(escaped_path.begin(), escaped_path.end(), '/', '\\');
37   FilePath escaped_filepath(UTF8ToWide(escaped_path));
38 #elif defined(OS_POSIX)
39   // The correct encoding on Linux may not actually be UTF8.
40   FilePath escaped_filepath(escaped_path);
41 #endif
42 
43   IconManager* im = g_browser_process->icon_manager();
44   gfx::Image* icon = im->LookupIcon(escaped_filepath, IconLoader::NORMAL);
45 
46   if (icon) {
47     scoped_refptr<RefCountedBytes> icon_data(new RefCountedBytes);
48     gfx::PNGCodec::EncodeBGRASkBitmap(*icon, false, &icon_data->data);
49 
50     SendResponse(request_id, icon_data);
51   } else {
52     // Icon was not in cache, go fetch it slowly.
53     IconManager::Handle h = im->LoadIcon(escaped_filepath,
54         IconLoader::NORMAL,
55         &cancelable_consumer_,
56         NewCallback(this, &FileIconSource::OnFileIconDataAvailable));
57 
58     // Attach the ChromeURLDataManager request ID to the history request.
59     cancelable_consumer_.SetClientData(im, h, request_id);
60   }
61 }
62 
GetMimeType(const std::string &) const63 std::string FileIconSource::GetMimeType(const std::string&) const {
64   // Rely on image decoder inferring the correct type.
65   return std::string();
66 }
67 
OnFileIconDataAvailable(IconManager::Handle handle,gfx::Image * icon)68 void FileIconSource::OnFileIconDataAvailable(IconManager::Handle handle,
69                                              gfx::Image* icon) {
70   IconManager* im = g_browser_process->icon_manager();
71   int request_id = cancelable_consumer_.GetClientData(im, handle);
72 
73   if (icon) {
74     scoped_refptr<RefCountedBytes> icon_data(new RefCountedBytes);
75     gfx::PNGCodec::EncodeBGRASkBitmap(*icon, false, &icon_data->data);
76 
77     SendResponse(request_id, icon_data);
78   } else {
79     // TODO(glen): send a dummy icon.
80     SendResponse(request_id, NULL);
81   }
82 }
83