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 22 FileIconSource::FileIconSource() 23 : DataSource(kFileIconPath, MessageLoop::current()) {} 24 25 FileIconSource::~FileIconSource() { 26 cancelable_consumer_.CancelAllRequests(); 27 } 28 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 63 std::string FileIconSource::GetMimeType(const std::string&) const { 64 // Rely on image decoder inferring the correct type. 65 return std::string(); 66 } 67 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