diff options
-rw-r--r-- | chrome/browser/download/download_extension_test.cc | 20 | ||||
-rw-r--r-- | chrome/browser/icon_loader_chromeos.cc | 207 | ||||
-rw-r--r-- | chrome/browser/icon_manager_chromeos.cc | 12 | ||||
-rw-r--r-- | chrome/browser/resources/chromeos/active_downloads.js | 5 | ||||
-rw-r--r-- | chrome/browser/resources/downloads.js | 3 | ||||
-rw-r--r-- | chrome/browser/ui/webui/active_downloads_ui.cc | 4 | ||||
-rw-r--r-- | chrome/browser/ui/webui/downloads_dom_handler.cc | 10 | ||||
-rw-r--r-- | chrome/browser/ui/webui/fileicon_source.cc | 93 | ||||
-rw-r--r-- | chrome/browser/ui/webui/fileicon_source.h | 17 | ||||
-rw-r--r-- | chrome/browser/ui/webui/fileicon_source_chromeos.cc | 259 | ||||
-rw-r--r-- | chrome/browser/ui/webui/fileicon_source_chromeos.h | 33 | ||||
-rw-r--r-- | chrome/browser/ui/webui/fileicon_source_unittest.cc | 98 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 10 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 1 |
14 files changed, 419 insertions, 353 deletions
diff --git a/chrome/browser/download/download_extension_test.cc b/chrome/browser/download/download_extension_test.cc index 6060520..70a37b6 100644 --- a/chrome/browser/download/download_extension_test.cc +++ b/chrome/browser/download/download_extension_test.cc @@ -332,15 +332,7 @@ IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_PauseResumeCancel) { // Test downloads.getFileIcon() on in-progress, finished, cancelled and deleted // download items. -// TODO(asanka): Fails on ChromeOS (http://crbug.com/109677) -#if defined(OS_CHROMEOS) -#define MAYBE_DownloadsApi_FileIcon_Active \ - FAILS_DownloadsApi_FileIcon_Active -#else -#define MAYBE_DownloadsApi_FileIcon_Active DownloadsApi_FileIcon_Active -#endif -IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, - MAYBE_DownloadsApi_FileIcon_Active) { +IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_FileIcon_Active) { DownloadItem* download_item = CreateSlowTestDownload(); ASSERT_TRUE(download_item); @@ -439,15 +431,7 @@ IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, // whether they exist or not. If the file doesn't exist we should receive a // generic icon from the OS/toolkit that may or may not be specific to the file // type. -// TODO(asanka): Fails on ChromeOS (http://crbug.com/109677) -#if defined(OS_CHROMEOS) -#define MAYBE_DownloadsApi_FileIcon_History \ - FAILS_DownloadsApi_FileIcon_History -#else -#define MAYBE_DownloadsApi_FileIcon_History DownloadsApi_FileIcon_History -#endif -IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, - MAYBE_DownloadsApi_FileIcon_History) { +IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadsApi_FileIcon_History) { base::Time current(base::Time::Now()); FilePath real_path( downloads_directory().Append(FILE_PATH_LITERAL("real.txt"))); diff --git a/chrome/browser/icon_loader_chromeos.cc b/chrome/browser/icon_loader_chromeos.cc new file mode 100644 index 0000000..e47af46 --- /dev/null +++ b/chrome/browser/icon_loader_chromeos.cc @@ -0,0 +1,207 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/icon_loader.h" + +#include <map> +#include <string> +#include <utility> + +#include "base/bind.h" +#include "base/lazy_instance.h" +#include "base/message_loop.h" +#include "chrome/browser/icon_loader.h" +#include "grit/component_extension_resources.h" +#include "skia/ext/image_operations.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/canvas_skia.h" +#include "ui/gfx/codec/png_codec.h" +#include "ui/gfx/image/image.h" +#include "webkit/glue/image_decoder.h" + +namespace { + +// Used with GenerateBitmapWithSize() to indicate that the image shouldn't be +// resized. +const int kDoNotResize = -1; + +struct IdrBySize { + int idr_small; + int idr_normal; + int idr_large; +}; + +// Performs mapping of <file extension, icon size> to icon resource IDs. +class IconMapper { + public: + IconMapper(); + + // Lookup icon resource ID for a given filename |extension| and + // |icon_size|. Defaults to generic icons if there are no icons for the given + // extension. + int Lookup(const std::string& extension, IconLoader::IconSize icon_size); + + private: + typedef std::map<std::string, IdrBySize> ExtensionIconMap; + + ExtensionIconMap extension_icon_map_; +}; + +const IdrBySize kAudioIdrs = { + IDR_FILE_MANAGER_IMG_FILETYPE_AUDIO, + IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_AUDIO, + IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_AUDIO +}; +const IdrBySize kGenericIdrs = { + IDR_FILE_MANAGER_IMG_FILETYPE_GENERIC, + IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_GENERIC, + IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_GENERIC +}; +const IdrBySize kHtmlIdrs = { + IDR_FILE_MANAGER_IMG_FILETYPE_HTML, + IDR_FILE_MANAGER_IMG_FILETYPE_HTML, + IDR_FILE_MANAGER_IMG_FILETYPE_HTML +}; +const IdrBySize kImageIdrs = { + IDR_FILE_MANAGER_IMG_FILETYPE_IMAGE, + IDR_FILE_MANAGER_IMG_FILETYPE_IMAGE, + IDR_FILE_MANAGER_IMG_FILETYPE_IMAGE +}; +const IdrBySize kPdfIdrs = { + IDR_FILE_MANAGER_IMG_FILETYPE_PDF, + IDR_FILE_MANAGER_IMG_FILETYPE_PDF, + IDR_FILE_MANAGER_IMG_FILETYPE_PDF +}; +const IdrBySize kTextIdrs = { + IDR_FILE_MANAGER_IMG_FILETYPE_TEXT, + IDR_FILE_MANAGER_IMG_FILETYPE_TEXT, + IDR_FILE_MANAGER_IMG_FILETYPE_TEXT +}; +const IdrBySize kVideoIdrs = { + IDR_FILE_MANAGER_IMG_FILETYPE_VIDEO, + IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_VIDEO, + IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_VIDEO +}; + +IconMapper::IconMapper() { + // The code below should match translation in + // chrome/browser/resources/file_manager/js/file_manager.js + // chrome/browser/resources/file_manager/css/file_manager.css + // 'audio': /\.(mp3|m4a|oga|ogg|wav)$/i, + // 'html': /\.(html?)$/i, + // 'image': /\.(bmp|gif|jpe?g|ico|png|webp)$/i, + // 'pdf' : /\.(pdf)$/i, + // 'text': /\.(pod|rst|txt|log)$/i, + // 'video': /\.(mov|mp4|m4v|mpe?g4?|ogm|ogv|ogx|webm)$/i + + const ExtensionIconMap::value_type kExtensionIdrBySizeData[] = { +#if defined(GOOGLE_CHROME_BUILD) || defined(USE_PROPRIETARY_CODECS) + std::make_pair(".m4a", kAudioIdrs), + std::make_pair(".mp3", kAudioIdrs), + std::make_pair(".pdf", kPdfIdrs), + std::make_pair(".3gp", kVideoIdrs), + std::make_pair(".avi", kVideoIdrs), + std::make_pair(".m4v", kVideoIdrs), + std::make_pair(".mov", kVideoIdrs), + std::make_pair(".mp4", kVideoIdrs), + std::make_pair(".mpeg", kVideoIdrs), + std::make_pair(".mpg", kVideoIdrs), + std::make_pair(".mpeg4", kVideoIdrs), + std::make_pair(".mpg4", kVideoIdrs), +#endif + std::make_pair(".flac", kAudioIdrs), + std::make_pair(".oga", kAudioIdrs), + std::make_pair(".ogg", kAudioIdrs), + std::make_pair(".wav", kAudioIdrs), + std::make_pair(".htm", kHtmlIdrs), + std::make_pair(".html", kHtmlIdrs), + std::make_pair(".bmp", kImageIdrs), + std::make_pair(".gif", kImageIdrs), + std::make_pair(".ico", kImageIdrs), + std::make_pair(".jpeg", kImageIdrs), + std::make_pair(".jpg", kImageIdrs), + std::make_pair(".png", kImageIdrs), + std::make_pair(".webp", kImageIdrs), + std::make_pair(".log", kTextIdrs), + std::make_pair(".pod", kTextIdrs), + std::make_pair(".rst", kTextIdrs), + std::make_pair(".txt", kTextIdrs), + std::make_pair(".ogm", kVideoIdrs), + std::make_pair(".ogv", kVideoIdrs), + std::make_pair(".ogx", kVideoIdrs), + std::make_pair(".webm", kVideoIdrs), + }; + + const size_t kESize = arraysize(kExtensionIdrBySizeData); + ExtensionIconMap source(&kExtensionIdrBySizeData[0], + &kExtensionIdrBySizeData[kESize]); + extension_icon_map_.swap(source); +} + +int IconMapper::Lookup(const std::string& extension, + IconLoader::IconSize icon_size) { + DCHECK(icon_size == IconLoader::SMALL || + icon_size == IconLoader::NORMAL || + icon_size == IconLoader::LARGE); + ExtensionIconMap::const_iterator it = extension_icon_map_.find(extension); + const IdrBySize& idrbysize = + ((it == extension_icon_map_.end()) ? kGenericIdrs : it->second); + int idr = -1; + switch (icon_size) { + case IconLoader::SMALL: idr = idrbysize.idr_small; break; + case IconLoader::NORMAL: idr = idrbysize.idr_normal; break; + case IconLoader::LARGE: idr = idrbysize.idr_large; break; + case IconLoader::ALL: + default: + NOTREACHED(); + } + return idr; +} + +// Returns a copy of |source| that is |pixel_size| in width and height. If +// |pixel_size| is |kDoNotResize|, returns an unmodified copy of |source|. +// |source| must be a square image (width == height). +SkBitmap* GenerateBitmapWithSize(SkBitmap* source, int pixel_size) { + DCHECK(source); + DCHECK(source->width() == source->height()); + + if (pixel_size == kDoNotResize || source->width() == pixel_size) + return new SkBitmap(*source); + + return new SkBitmap(skia::ImageOperations::Resize( + *source, skia::ImageOperations::RESIZE_BEST, pixel_size, pixel_size)); +} + +int IconSizeToPixelSize(IconLoader::IconSize size) { + switch (size) { + case IconLoader::SMALL: return 16; + case IconLoader::NORMAL: return 32; + case IconLoader::LARGE: // fallthrough + // On ChromeOS, we consider LARGE to mean "the largest image we have." + // Since we have already chosen the largest applicable image resource, we + // return the image as-is. + case IconLoader::ALL: // fallthrough + default: + return kDoNotResize; + } +} + +} // namespace + +void IconLoader::ReadIcon() { + static base::LazyInstance<IconMapper>::Leaky icon_mapper = + LAZY_INSTANCE_INITIALIZER; + int idr = icon_mapper.Get().Lookup(group_, icon_size_); + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + scoped_refptr<RefCountedStaticMemory> bytes(rb.LoadDataResourceBytes(idr)); + DCHECK(bytes.get()); + SkBitmap bitmap; + if (!gfx::PNGCodec::Decode(bytes->front(), bytes->size(), &bitmap)) + NOTREACHED(); + image_.reset(new gfx::Image( + GenerateBitmapWithSize(&bitmap, IconSizeToPixelSize(icon_size_)))); + target_message_loop_->PostTask( + FROM_HERE, base::Bind(&IconLoader::NotifyDelegate, this)); +} diff --git a/chrome/browser/icon_manager_chromeos.cc b/chrome/browser/icon_manager_chromeos.cc new file mode 100644 index 0000000..2f82c8f --- /dev/null +++ b/chrome/browser/icon_manager_chromeos.cc @@ -0,0 +1,12 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/icon_manager.h" + +#include "base/file_path.h" +#include "base/string_util.h" + +IconGroupID IconManager::GetGroupIDFromFilepath(const FilePath& filepath) { + return StringToLowerASCII(filepath.Extension()); +} diff --git a/chrome/browser/resources/chromeos/active_downloads.js b/chrome/browser/resources/chromeos/active_downloads.js index 3615d59..1937c11 100644 --- a/chrome/browser/resources/chromeos/active_downloads.js +++ b/chrome/browser/resources/chromeos/active_downloads.js @@ -233,10 +233,11 @@ DownloadRow.prototype = { }, setDangerousIcon_: function(warning) { + var escapedPath = encodeURIComponent(this.path).replace(/'/g,'%27'); this.icon.className = warning ? 'iconwarning' : 'icon'; this.icon.style.background = warning ? '' : - 'url(chrome://fileicon' + escape(this.path) + - '?iconsize=small) no-repeat'; + 'url(\'chrome://fileicon/' + escapedPath + + '?iconsize=small\') no-repeat'; }, /** diff --git a/chrome/browser/resources/downloads.js b/chrome/browser/resources/downloads.js index ecdba4e..735326c 100644 --- a/chrome/browser/resources/downloads.js +++ b/chrome/browser/resources/downloads.js @@ -394,7 +394,8 @@ Download.prototype.update = function(download) { this.safe_.style.display = 'none'; } else { downloads.scheduleIconLoad(this.nodeImg_, - 'chrome://fileicon/' + this.filePath_); + 'chrome://fileicon/' + + encodeURIComponent(this.filePath_)); if (this.state_ == Download.States.COMPLETE && !this.fileExternallyRemoved_) { diff --git a/chrome/browser/ui/webui/active_downloads_ui.cc b/chrome/browser/ui/webui/active_downloads_ui.cc index 669a97c..d12bd50 100644 --- a/chrome/browser/ui/webui/active_downloads_ui.cc +++ b/chrome/browser/ui/webui/active_downloads_ui.cc @@ -38,7 +38,7 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/browser/ui/webui/chrome_web_ui_data_source.h" -#include "chrome/browser/ui/webui/fileicon_source_chromeos.h" +#include "chrome/browser/ui/webui/fileicon_source.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/url_constants.h" @@ -181,7 +181,7 @@ ActiveDownloadsHandler::~ActiveDownloadsHandler() { void ActiveDownloadsHandler::RegisterMessages() { profile_ = Profile::FromWebUI(web_ui()); - profile_->GetChromeURLDataManager()->AddDataSource(new FileIconSourceCros()); + profile_->GetChromeURLDataManager()->AddDataSource(new FileIconSource()); web_ui()->RegisterMessageCallback("getDownloads", base::Bind(&ActiveDownloadsHandler::HandleGetDownloads, diff --git a/chrome/browser/ui/webui/downloads_dom_handler.cc b/chrome/browser/ui/webui/downloads_dom_handler.cc index d1fc345..d93c50c 100644 --- a/chrome/browser/ui/webui/downloads_dom_handler.cc +++ b/chrome/browser/ui/webui/downloads_dom_handler.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -27,7 +27,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/chrome_url_data_manager.h" #include "chrome/browser/ui/webui/fileicon_source.h" -#include "chrome/browser/ui/webui/fileicon_source_chromeos.h" #include "chrome/common/url_constants.h" #include "content/public/browser/download_item.h" #include "content/public/browser/user_metrics.h" @@ -128,12 +127,7 @@ DownloadsDOMHandler::DownloadsDOMHandler(DownloadManager* dlm) download_manager_(dlm) { // Create our fileicon data source. Profile::FromBrowserContext(dlm->GetBrowserContext())-> - GetChromeURLDataManager()->AddDataSource( -#if defined(OS_CHROMEOS) - new FileIconSourceCros()); -#else - new FileIconSource()); -#endif // OS_CHROMEOS + GetChromeURLDataManager()->AddDataSource(new FileIconSource()); } DownloadsDOMHandler::~DownloadsDOMHandler() { diff --git a/chrome/browser/ui/webui/fileicon_source.cc b/chrome/browser/ui/webui/fileicon_source.cc index 30ee3da..17d10c5 100644 --- a/chrome/browser/ui/webui/fileicon_source.cc +++ b/chrome/browser/ui/webui/fileicon_source.cc @@ -1,48 +1,93 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/ui/webui/fileicon_source.h" +#include "base/basictypes.h" #include "base/callback.h" #include "base/file_path.h" #include "base/memory/ref_counted_memory.h" +#include "base/string_split.h" #include "base/utf_string_conversions.h" #include "chrome/browser/browser_process.h" #include "chrome/common/time_format.h" +#include "googleurl/src/gurl.h" #include "grit/generated_resources.h" #include "net/base/escape.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/codec/png_codec.h" #include "ui/gfx/image/image.h" -// The path used in internal URLs to file icon data. -static const char kFileIconPath[] = "fileicon"; +namespace { -FileIconSource::FileIconSource() - : DataSource(kFileIconPath, MessageLoop::current()) {} +typedef std::map<std::string, IconLoader::IconSize> QueryIconSizeMap; -FileIconSource::~FileIconSource() { - cancelable_consumer_.CancelAllRequests(); -} +// The path used in internal URLs to file icon data. +const char kFileIconPath[] = "fileicon"; -void FileIconSource::StartDataRequest(const std::string& path, - bool is_incognito, - int request_id) { - std::string escaped_path = net::UnescapeURLComponent(path, - net::UnescapeRule::SPACES); +// URL parameter specifying icon size. +const char kIconSize[] = "iconsize"; + +// Assuming the url is of the form '/path?query', convert the path portion into +// a FilePath and return the resulting |file_path| and |query|. The path +// portion may have been encoded using encodeURIComponent(). +void GetFilePathAndQuery(const std::string& url, + FilePath* file_path, + std::string* query) { + // We receive the url with chrome://fileicon/ stripped but GURL expects it. + const GURL gurl("chrome://fileicon/" + url); + std::string path = + net::UnescapeURLComponent(gurl.path().substr(1), + (net::UnescapeRule::URL_SPECIAL_CHARS | + net::UnescapeRule::SPACES)); #if defined(OS_WIN) // The path we receive has the wrong slashes and escaping for what we need; // this only appears to matter for getting icons from .exe files. - std::replace(escaped_path.begin(), escaped_path.end(), '/', '\\'); - FilePath escaped_filepath(UTF8ToWide(escaped_path)); + std::replace(path.begin(), path.end(), '/', '\\'); + *file_path = FilePath(UTF8ToWide(path)); #elif defined(OS_POSIX) // The correct encoding on Linux may not actually be UTF8. - FilePath escaped_filepath(escaped_path); + *file_path = FilePath(path); #endif + query->assign(gurl.query()); +} + +IconLoader::IconSize SizeStringToIconSize(const std::string& size_string) { + if (size_string == "small") return IconLoader::SMALL; + if (size_string == "large") return IconLoader::LARGE; + // We default to NORMAL if we don't recognize the size_string. Including + // size_string=="normal". + return IconLoader::NORMAL; +} + +// Simple parser for data on the query. +IconLoader::IconSize QueryToIconSize(const std::string& query) { + typedef std::pair<std::string, std::string> KVPair; + std::vector<KVPair> parameters; + base::SplitStringIntoKeyValuePairs(query, '=', '&', ¶meters); + for (std::vector<KVPair>::const_iterator iter = parameters.begin(); + iter != parameters.end(); ++iter) { + if (iter->first == kIconSize) + return SizeStringToIconSize(iter->second); + } + return IconLoader::NORMAL; +} + +} // namespace + +FileIconSource::FileIconSource() + : DataSource(kFileIconPath, MessageLoop::current()) {} + +FileIconSource::~FileIconSource() { + cancelable_consumer_.CancelAllRequests(); +} +void FileIconSource::FetchFileIcon(const FilePath& path, + IconLoader::IconSize icon_size, + int request_id) { IconManager* im = g_browser_process->icon_manager(); - gfx::Image* icon = im->LookupIcon(escaped_filepath, IconLoader::NORMAL); + gfx::Image* icon = im->LookupIcon(path, icon_size); if (icon) { scoped_refptr<RefCountedBytes> icon_data(new RefCountedBytes); @@ -51,9 +96,8 @@ void FileIconSource::StartDataRequest(const std::string& path, SendResponse(request_id, icon_data); } else { // Icon was not in cache, go fetch it slowly. - IconManager::Handle h = im->LoadIcon(escaped_filepath, - IconLoader::NORMAL, - &cancelable_consumer_, + IconManager::Handle h = im->LoadIcon( + path, icon_size, &cancelable_consumer_, base::Bind(&FileIconSource::OnFileIconDataAvailable, base::Unretained(this))); @@ -62,6 +106,15 @@ void FileIconSource::StartDataRequest(const std::string& path, } } +void FileIconSource::StartDataRequest(const std::string& url_path, + bool is_incognito, + int request_id) { + std::string query; + FilePath file_path; + GetFilePathAndQuery(url_path, &file_path, &query); + FetchFileIcon(file_path, QueryToIconSize(query), request_id); +} + std::string FileIconSource::GetMimeType(const std::string&) const { // Rely on image decoder inferring the correct type. return std::string(); diff --git a/chrome/browser/ui/webui/fileicon_source.h b/chrome/browser/ui/webui/fileicon_source.h index f42fabf..84858c7 100644 --- a/chrome/browser/ui/webui/fileicon_source.h +++ b/chrome/browser/ui/webui/fileicon_source.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,6 +8,7 @@ #include <string> +#include "base/file_path.h" #include "chrome/browser/icon_manager.h" #include "chrome/browser/ui/webui/chrome_url_data_manager.h" @@ -36,14 +37,18 @@ class FileIconSource : public ChromeURLDataManager::DataSource { IconManager::Handle request_handle, gfx::Image* icon); - private: + protected: virtual ~FileIconSource(); - CancelableRequestConsumerT<int, 0> cancelable_consumer_; + // Once the |path| and |icon_size| has been determined from the request, this + // function is called to perform the actual fetch. Declared as virtual for + // testing. + virtual void FetchFileIcon(const FilePath& path, + IconLoader::IconSize icon_size, + int request_id); - // Raw PNG representation of the favicon to show when the favicon - // database doesn't have a favicon for a webpage. - scoped_refptr<RefCountedBytes> default_favicon_; + private: + CancelableRequestConsumerT<int, 0> cancelable_consumer_; DISALLOW_COPY_AND_ASSIGN(FileIconSource); }; diff --git a/chrome/browser/ui/webui/fileicon_source_chromeos.cc b/chrome/browser/ui/webui/fileicon_source_chromeos.cc deleted file mode 100644 index d0dc1d5..0000000 --- a/chrome/browser/ui/webui/fileicon_source_chromeos.cc +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/ui/webui/fileicon_source_chromeos.h" - -#include <map> -#include <utility> -#include <vector> - -#include "base/file_util.h" -#include "base/memory/singleton.h" -#include "base/string_split.h" -#include "base/string_util.h" -#include "base/threading/thread_restrictions.h" -#include "chrome/browser/icon_loader.h" -#include "chrome/browser/io_thread.h" -#include "chrome/browser/ui/webui/chrome_url_data_manager.h" -#include "chrome/common/url_constants.h" -#include "googleurl/src/gurl.h" -#include "grit/component_extension_resources.h" -#include "grit/component_extension_resources_map.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "grit/ui_resources.h" -#include "net/base/escape.h" -#include "net/base/mime_util.h" -#include "ui/base/resource/resource_bundle.h" - -namespace { - -struct IdrBySize { - int idr_small_; - int idr_normal_; - int idr_large_; -}; - -typedef std::map<std::string, IconLoader::IconSize> QueryIconSizeMap; -typedef std::map<std::string, IdrBySize> ExtensionIconSizeMap; - -const char *kIconSize = "iconsize"; - -const IdrBySize kAudioIdrs = { - IDR_FILE_MANAGER_IMG_FILETYPE_AUDIO, - IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_AUDIO, - IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_AUDIO -}; -const IdrBySize kDeviceIdrs = { - IDR_FILE_MANAGER_IMG_FILETYPE_DEVICE, - IDR_FILE_MANAGER_IMG_FILETYPE_DEVICE, - IDR_FILE_MANAGER_IMG_FILETYPE_DEVICE -}; -const IdrBySize kDocIdrs = { - IDR_FILE_MANAGER_IMG_FILETYPE_DOC, - IDR_FILE_MANAGER_IMG_FILETYPE_DOC, - IDR_FILE_MANAGER_IMG_FILETYPE_DOC -}; -const IdrBySize kFolderIdrs = { - IDR_FILE_MANAGER_IMG_FILETYPE_FOLDER, - IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_FOLDER, - IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_FOLDER -}; -const IdrBySize kGenericIdrs = { - IDR_FILE_MANAGER_IMG_FILETYPE_GENERIC, - IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_GENERIC, - IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_GENERIC -}; -const IdrBySize kHtmlIdrs = { - IDR_FILE_MANAGER_IMG_FILETYPE_HTML, - IDR_FILE_MANAGER_IMG_FILETYPE_HTML, - IDR_FILE_MANAGER_IMG_FILETYPE_HTML -}; -const IdrBySize kImageIdrs = { - IDR_FILE_MANAGER_IMG_FILETYPE_IMAGE, - IDR_FILE_MANAGER_IMG_FILETYPE_IMAGE, - IDR_FILE_MANAGER_IMG_FILETYPE_IMAGE -}; -const IdrBySize kPdfIdrs = { - IDR_FILE_MANAGER_IMG_FILETYPE_PDF, - IDR_FILE_MANAGER_IMG_FILETYPE_PDF, - IDR_FILE_MANAGER_IMG_FILETYPE_PDF -}; -const IdrBySize kPresentationIdrs = { - IDR_FILE_MANAGER_IMG_FILETYPE_PRESENTATION, - IDR_FILE_MANAGER_IMG_FILETYPE_PRESENTATION, - IDR_FILE_MANAGER_IMG_FILETYPE_PRESENTATION -}; -const IdrBySize kSpreadsheetIdrs = { - IDR_FILE_MANAGER_IMG_FILETYPE_SPREADSHEET, - IDR_FILE_MANAGER_IMG_FILETYPE_SPREADSHEET, - IDR_FILE_MANAGER_IMG_FILETYPE_SPREADSHEET -}; -const IdrBySize kUnreadableDeviceIdrs = { - IDR_FILE_MANAGER_IMG_FILETYPE_UNREADABLE_DEVICE, - IDR_FILE_MANAGER_IMG_FILETYPE_UNREADABLE_DEVICE, - IDR_FILE_MANAGER_IMG_FILETYPE_UNREADABLE_DEVICE -}; -const IdrBySize kTextIdrs = { - IDR_FILE_MANAGER_IMG_FILETYPE_TEXT, - IDR_FILE_MANAGER_IMG_FILETYPE_TEXT, - IDR_FILE_MANAGER_IMG_FILETYPE_TEXT -}; -const IdrBySize kVideoIdrs = { - IDR_FILE_MANAGER_IMG_FILETYPE_VIDEO, - IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_VIDEO, - IDR_FILE_MANAGER_IMG_FILETYPE_LARGE_VIDEO -}; - -QueryIconSizeMap BuildQueryIconSizeMap() { - QueryIconSizeMap::value_type kQueryIconSizeData[] = { - std::make_pair("small", IconLoader::SMALL), - std::make_pair("normal", IconLoader::NORMAL), - std::make_pair("large", IconLoader::LARGE) - }; - - size_t kQSize = arraysize(kQueryIconSizeData); - return QueryIconSizeMap(&kQueryIconSizeData[0], - &kQueryIconSizeData[kQSize]); -} - -// The code below should match translation in -// chrome/browser/resources/file_manager/js/file_manager.js -// chrome/browser/resources/file_manager/css/file_manager.css -// 'audio': /\.(mp3|m4a|oga|ogg|wav)$/i, -// 'html': /\.(html?)$/i, -// 'image': /\.(bmp|gif|jpe?g|ico|png|webp)$/i, -// 'pdf' : /\.(pdf)$/i, -// 'text': /\.(pod|rst|txt|log)$/i, -// 'video': /\.(mov|mp4|m4v|mpe?g4?|ogm|ogv|ogx|webm)$/i - -ExtensionIconSizeMap BuildExtensionIdrSizeMap() { - const ExtensionIconSizeMap::value_type kExtensionIdrBySizeData[] = { -#if defined(GOOGLE_CHROME_BUILD) || defined(USE_PROPRIETARY_CODECS) - std::make_pair(".m4a", kAudioIdrs), - std::make_pair(".mp3", kAudioIdrs), - std::make_pair(".pdf", kPdfIdrs), - std::make_pair(".3gp", kVideoIdrs), - std::make_pair(".avi", kVideoIdrs), - std::make_pair(".m4v", kVideoIdrs), - std::make_pair(".mov", kVideoIdrs), - std::make_pair(".mp4", kVideoIdrs), - std::make_pair(".mpeg", kVideoIdrs), - std::make_pair(".mpg", kVideoIdrs), - std::make_pair(".mpeg4", kVideoIdrs), - std::make_pair(".mpg4", kVideoIdrs), -#endif - std::make_pair(".flac", kAudioIdrs), - std::make_pair(".oga", kAudioIdrs), - std::make_pair(".ogg", kAudioIdrs), - std::make_pair(".wav", kAudioIdrs), - std::make_pair(".htm", kHtmlIdrs), - std::make_pair(".html", kHtmlIdrs), - std::make_pair(".bmp", kImageIdrs), - std::make_pair(".gif", kImageIdrs), - std::make_pair(".ico", kImageIdrs), - std::make_pair(".jpeg", kImageIdrs), - std::make_pair(".jpg", kImageIdrs), - std::make_pair(".png", kImageIdrs), - std::make_pair(".webp", kImageIdrs), - std::make_pair(".log", kTextIdrs), - std::make_pair(".pod", kTextIdrs), - std::make_pair(".rst", kTextIdrs), - std::make_pair(".txt", kTextIdrs), - std::make_pair(".ogm", kVideoIdrs), - std::make_pair(".ogv", kVideoIdrs), - std::make_pair(".ogx", kVideoIdrs), - std::make_pair(".webm", kVideoIdrs), - }; - - const size_t kESize = arraysize(kExtensionIdrBySizeData); - return ExtensionIconSizeMap(&kExtensionIdrBySizeData[0], - &kExtensionIdrBySizeData[kESize]); -} - -// Split on the very first &. The first part is path, the rest query. -void GetExtensionAndQuery(const std::string& url, - std::string* extension, - std::string* query) { - // We receive the url with chrome://fileicon/ stripped but GURL expects it. - const GURL gurl("chrome://fileicon/" + net::EscapePath(url)); - const std::string path = gurl.path(); - *extension = StringToLowerASCII(FilePath(path).Extension()); - *query = gurl.query(); -} - -// Simple parser for data on the query. -IconLoader::IconSize QueryToIconSize(const std::string& query) { - CR_DEFINE_STATIC_LOCAL( - QueryIconSizeMap, kQueryIconSizeMap, (BuildQueryIconSizeMap())); - typedef std::pair<std::string, std::string> KVPair; - std::vector<KVPair> parameters; - if (base::SplitStringIntoKeyValuePairs(query, '=', '&', ¶meters)) { - for (std::vector<KVPair>::const_iterator itk = parameters.begin(); - itk != parameters.end(); ++itk) { - if (itk->first == kIconSize) { - QueryIconSizeMap::const_iterator itq( - kQueryIconSizeMap.find(itk->second)); - if (itq != kQueryIconSizeMap.end()) - return itq->second; - } - } - } - return IconLoader::NORMAL; -} - -// Finds matching resource of proper size. Fallback to generic. -int UrlToIDR(const std::string& url) { - CR_DEFINE_STATIC_LOCAL( - ExtensionIconSizeMap, kExtensionIdrSizeMap, (BuildExtensionIdrSizeMap())); - std::string extension, query; - int idr = -1; - GetExtensionAndQuery(url, &extension, &query); - const IconLoader::IconSize size = QueryToIconSize(query); - ExtensionIconSizeMap::const_iterator it = - kExtensionIdrSizeMap.find(extension); - if (it != kExtensionIdrSizeMap.end()) { - IdrBySize idrbysize = it->second; - if (size == IconLoader::SMALL) { - idr = idrbysize.idr_small_; - } else if (size == IconLoader::NORMAL) { - idr = idrbysize.idr_normal_; - } else if (size == IconLoader::LARGE) { - idr = idrbysize.idr_large_; - } - } - if (idr == -1) { - if (size == IconLoader::SMALL) { - idr = kGenericIdrs.idr_small_; - } else if (size == IconLoader::NORMAL) { - idr = kGenericIdrs.idr_normal_; - } else { - idr = kGenericIdrs.idr_large_; - } - } - return idr; -} -} // namespace - -FileIconSourceCros::FileIconSourceCros() - : DataSource("fileicon", NULL) { -} - -FileIconSourceCros::~FileIconSourceCros() { -} - -void FileIconSourceCros::StartDataRequest(const std::string& url, - bool is_incognito, - int request_id) { - int idr = UrlToIDR(url); - const ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - scoped_refptr<RefCountedStaticMemory> bytes(rb.LoadDataResourceBytes(idr)); - SendResponse(request_id, bytes); -} - -// The mime type refers to the type of the response/icon served. -std::string FileIconSourceCros::GetMimeType( - const std::string& url) const { - return "image/png"; -} diff --git a/chrome/browser/ui/webui/fileicon_source_chromeos.h b/chrome/browser/ui/webui/fileicon_source_chromeos.h deleted file mode 100644 index 5471875..0000000 --- a/chrome/browser/ui/webui/fileicon_source_chromeos.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_WEBUI_FILEICON_SOURCE_CHROMEOS_H_ -#define CHROME_BROWSER_UI_WEBUI_FILEICON_SOURCE_CHROMEOS_H_ -#pragma once - -#include <string> - -#include "base/compiler_specific.h" -#include "chrome/browser/ui/webui/chrome_url_data_manager.h" - -// A DataSource for chrome://fileicon/ URLs, but reads from -// resources instead of disk. Allows for parameterization -// via chrome://fileicon/path.ext?size=[small|medium|large] -class FileIconSourceCros : public ChromeURLDataManager::DataSource { - public: - FileIconSourceCros(); - - // Overridden from ChromeURLDataManager::DataSource. - virtual void StartDataRequest(const std::string& url, - bool is_incognito, - int request_id) OVERRIDE; - virtual std::string GetMimeType(const std::string&) const OVERRIDE; - - private: - virtual ~FileIconSourceCros(); - - DISALLOW_COPY_AND_ASSIGN(FileIconSourceCros); -}; - -#endif // CHROME_BROWSER_UI_WEBUI_FILEICON_SOURCE_CHROMEOS_H_ diff --git a/chrome/browser/ui/webui/fileicon_source_unittest.cc b/chrome/browser/ui/webui/fileicon_source_unittest.cc new file mode 100644 index 0000000..1918709 --- /dev/null +++ b/chrome/browser/ui/webui/fileicon_source_unittest.cc @@ -0,0 +1,98 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/memory/ref_counted_memory.h" +#include "base/message_loop.h" +#include "chrome/browser/icon_manager.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/fileicon_source.h" +#include "chrome/test/base/testing_profile.h" +#include "content/test/test_browser_thread.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/gmock/include/gmock/gmock.h" + +using content::BrowserThread; + +namespace { + +class TestFileIconSource : public FileIconSource { + public: + explicit TestFileIconSource() {} + + MOCK_METHOD3(FetchFileIcon, void(const FilePath& path, + IconLoader::IconSize icon_size, + int request_id)); +}; + +class FileIconSourceTest : public testing::Test { + public: + FileIconSourceTest() + : loop_(MessageLoop::TYPE_UI), + ui_thread_(BrowserThread::UI, MessageLoop::current()), + file_thread_(BrowserThread::FILE, MessageLoop::current()) {} + + static TestFileIconSource* CreateFileIconSource() { + return new TestFileIconSource(); + } + + private: + MessageLoop loop_; + content::TestBrowserThread ui_thread_; + content::TestBrowserThread file_thread_; +}; + +const struct FetchFileIconExpectation { + const char* request_path; + const FilePath::CharType* unescaped_path; + IconLoader::IconSize size; +} kBasicExpectations[] = { + { "foo?bar", FILE_PATH_LITERAL("foo"), IconLoader::NORMAL }, + { "foo?iconsize=small", FILE_PATH_LITERAL("foo"), IconLoader::SMALL }, + { "foo?iconsize=normal", FILE_PATH_LITERAL("foo"), IconLoader::NORMAL }, + { "foo?iconsize=large", FILE_PATH_LITERAL("foo"), IconLoader::LARGE }, + { "foo?iconsize=asdf", FILE_PATH_LITERAL("foo"), IconLoader::NORMAL }, + { "foo?blah=b&iconsize=small", FILE_PATH_LITERAL("foo"), IconLoader::SMALL }, + { "foo?blah&iconsize=small", FILE_PATH_LITERAL("foo"), IconLoader::SMALL }, + { "a%3Fb%26c%3Dd.txt?iconsize=small", FILE_PATH_LITERAL("a?b&c=d.txt"), + IconLoader::SMALL }, + { "a%3Ficonsize%3Dsmall?iconsize=large", + FILE_PATH_LITERAL("a?iconsize=small"), IconLoader::LARGE }, + { "o%40%23%24%25%26*()%20%2B%3D%3F%2C%3A%3B%22.jpg", + FILE_PATH_LITERAL("o@#$%&*() +=?,:;\".jpg"), IconLoader::NORMAL }, +#if defined(OS_WIN) + { "c:/foo/bar/baz", FILE_PATH_LITERAL("c:\\foo\\bar\\baz"), + IconLoader::NORMAL }, + { "/foo?bar=asdf&asdf", FILE_PATH_LITERAL("\\foo"), IconLoader::NORMAL }, + { "c%3A%2Fusers%2Ffoo%20user%2Fbar.txt", + FILE_PATH_LITERAL("c:\\users\\foo user\\bar.txt"), IconLoader::NORMAL }, + { "c%3A%2Fusers%2F%C2%A9%202000.pdf", + FILE_PATH_LITERAL("c:\\users\\\xa9 2000.pdf"), IconLoader::NORMAL }, + { "%E0%B6%9A%E0%B6%BB%E0%B7%9D%E0%B6%B8%E0%B7%8A", + FILE_PATH_LITERAL("\x0d9a\x0dbb\x0ddd\x0db8\x0dca"), IconLoader::NORMAL }, + { "%2Ffoo%2Fbar", FILE_PATH_LITERAL("\\foo\\bar"), IconLoader::NORMAL }, + { "%2Fbaz%20(1).txt?iconsize=small", FILE_PATH_LITERAL("\\baz (1).txt"), + IconLoader::SMALL }, +#else + { "/foo/bar/baz", FILE_PATH_LITERAL("/foo/bar/baz"), IconLoader::NORMAL }, + { "/foo?bar", FILE_PATH_LITERAL("/foo"), IconLoader::NORMAL }, + { "%2Ffoo%2f%E0%B6%9A%E0%B6%BB%E0%B7%9D%E0%B6%B8%E0%B7%8A", + FILE_PATH_LITERAL("/foo/\xe0\xb6\x9a\xe0\xb6\xbb\xe0\xb7\x9d") + FILE_PATH_LITERAL("\xe0\xb6\xb8\xe0\xb7\x8a"), IconLoader::NORMAL }, + { "%2Ffoo%2Fbar", FILE_PATH_LITERAL("/foo/bar"), IconLoader::NORMAL }, + { "%2Fbaz%20(1).txt?iconsize=small", FILE_PATH_LITERAL("/baz (1).txt"), + IconLoader::SMALL }, +#endif +}; + +} // namespace + +TEST_F(FileIconSourceTest, FileIconSource_Parse) { + for (unsigned i = 0; i < arraysize(kBasicExpectations); i++) { + scoped_refptr<TestFileIconSource> source(CreateFileIconSource()); + EXPECT_CALL(*source.get(), + FetchFileIcon(FilePath(kBasicExpectations[i].unescaped_path), + kBasicExpectations[i].size, i)); + source->StartDataRequest(kBasicExpectations[i].request_path, false, i); + } +} diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 7a12bdc..6c06411 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1450,11 +1450,13 @@ 'browser/history/visitsegment_database.h', 'browser/icon_loader.cc', 'browser/icon_loader.h', + 'browser/icon_loader_chromeos.cc', 'browser/icon_loader_linux.cc', 'browser/icon_loader_mac.mm', 'browser/icon_loader_win.cc', 'browser/icon_manager.cc', 'browser/icon_manager.h', + 'browser/icon_manager_chromeos.cc', 'browser/icon_manager_linux.cc', 'browser/icon_manager_mac.mm', 'browser/icon_manager_win.cc', @@ -3840,8 +3842,6 @@ 'browser/ui/webui/favicon_source.h', 'browser/ui/webui/fileicon_source.cc', 'browser/ui/webui/fileicon_source.h', - 'browser/ui/webui/fileicon_source_chromeos.cc', - 'browser/ui/webui/fileicon_source_chromeos.h', 'browser/ui/webui/flags_ui.cc', 'browser/ui/webui/flags_ui.h', 'browser/ui/webui/flash_ui.cc', @@ -4279,6 +4279,8 @@ ['exclude', 'browser/extensions/extension_input_method_api.cc'], ['exclude', 'browser/extensions/extension_input_method_api.h'], ['exclude', 'browser/extensions/extension_tts_api_chromeos.cc'], + ['exclude', 'browser/icon_loader_chromeos.cc'], + ['exclude', 'browser/icon_manager_chromeos.cc'], ['exclude', 'browser/oom_priority_manager.cc'], ['exclude', 'browser/oom_priority_manager.h'], ['exclude', 'browser/policy/auto_enrollment_client.cc'], @@ -4305,8 +4307,6 @@ ['exclude', 'browser/ui/webui/about_page/about_page_ui.cc'], ['exclude', 'browser/ui/webui/about_page/about_page_ui.h'], ['exclude', 'browser/ui/webui/active_downloads_ui.cc'], - ['exclude', 'browser/ui/webui/fileicon_source_chromeos.cc'], - ['exclude', 'browser/ui/webui/fileicon_source_chromeos.h'], ], }], ['chromeos==1', { @@ -4323,6 +4323,8 @@ 'browser/first_run/upgrade_util.cc', 'browser/first_run/upgrade_util.h', 'browser/first_run/upgrade_util_linux.cc', + 'browser/icon_loader_linux.cc', + 'browser/icon_manager_linux.cc', 'browser/idle_linux.cc', 'browser/password_manager/native_backend_gnome_x.cc', 'browser/password_manager/native_backend_gnome_x.h', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index ff1a325..deadf16 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1971,6 +1971,7 @@ 'browser/ui/views/tabs/fake_base_tab_strip_controller.h', 'browser/ui/views/tabs/tab_strip_unittest.cc', 'browser/ui/webui/chrome_web_ui_data_source_unittest.cc', + 'browser/ui/webui/fileicon_source_unittest.cc', 'browser/ui/webui/html_dialog_tab_contents_delegate_unittest.cc', 'browser/ui/webui/options/chromeos/virtual_keyboard_manager_handler_unittest.cc', 'browser/ui/webui/options/language_options_handler_unittest.cc', |