blob: 5a0a51e1161c4abc3ba610c9f281be31b0a5e895 [file] [log] [blame]
[email protected]25cc7502012-01-31 19:33:551// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]12e14fc2009-02-19 22:25:222// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]fd42ac30f2011-02-27 19:33:365#include "chrome/browser/ui/webui/fileicon_source.h"
[email protected]12e14fc2009-02-19 22:25:226
[email protected]c1896982012-12-05 20:26:177#include "base/bind.h"
[email protected]2041cf342010-02-19 03:15:598#include "base/callback.h"
[email protected]57999812013-02-24 05:40:529#include "base/files/file_path.h"
[email protected]3b63f8f42011-03-28 01:54:1510#include "base/memory/ref_counted_memory.h"
[email protected]1988e1c2013-02-28 20:27:4211#include "base/strings/string_split.h"
[email protected]774cc3c2013-06-07 20:26:4512#include "base/strings/utf_string_conversions.h"
[email protected]12e14fc2009-02-19 22:25:2213#include "chrome/browser/browser_process.h"
Dan Beamb0dba212019-04-20 03:25:1914#include "chrome/common/webui_url_constants.h"
[email protected]43437692009-03-04 04:07:3415#include "net/base/escape.h"
Dan Beamb0dba212019-04-20 03:25:1916#include "net/base/url_util.h"
[email protected]66171ab2011-03-03 15:50:0717#include "third_party/skia/include/core/SkBitmap.h"
[email protected]cd67ed52013-10-15 01:22:1318#include "ui/base/webui/web_ui_util.h"
[email protected]08397d52011-02-05 01:53:3819#include "ui/gfx/codec/png_codec.h"
[email protected]f08e0512011-06-13 18:10:4420#include "ui/gfx/image/image.h"
[email protected]daf19c52012-07-13 19:01:3221#include "ui/gfx/image/image_skia.h"
[email protected]a6483d22013-07-03 22:11:0022#include "url/gurl.h"
[email protected]12e14fc2009-02-19 22:25:2223
[email protected]25cc7502012-01-31 19:33:5524namespace {
25
26typedef std::map<std::string, IconLoader::IconSize> QueryIconSizeMap;
27
[email protected]12e14fc2009-02-19 22:25:2228// The path used in internal URLs to file icon data.
[email protected]25cc7502012-01-31 19:33:5529const char kFileIconPath[] = "fileicon";
30
31// URL parameter specifying icon size.
Daniel Bratell61e70992018-06-12 10:32:3732const char kIconSizeParameter[] = "iconsize";
[email protected]25cc7502012-01-31 19:33:5533
Dan Beamb0dba212019-04-20 03:25:1934// URL parameter specifying the file path for which to get an icon.
35const char kPathParameter[] = "path";
36
[email protected]daf19c52012-07-13 19:01:3237// URL parameter specifying scale factor.
Daniel Bratell61e70992018-06-12 10:32:3738const char kScaleFactorParameter[] = "scale";
[email protected]daf19c52012-07-13 19:01:3239
[email protected]25cc7502012-01-31 19:33:5540IconLoader::IconSize SizeStringToIconSize(const std::string& size_string) {
41 if (size_string == "small") return IconLoader::SMALL;
42 if (size_string == "large") return IconLoader::LARGE;
43 // We default to NORMAL if we don't recognize the size_string. Including
44 // size_string=="normal".
45 return IconLoader::NORMAL;
46}
47
Dan Beamb0dba212019-04-20 03:25:1948void ParseQueryParams(const std::string& path,
49 base::FilePath* file_path,
[email protected]33cff1d2014-05-21 16:05:4850 float* scale_factor,
[email protected]daf19c52012-07-13 19:01:3251 IconLoader::IconSize* icon_size) {
Dan Beamb0dba212019-04-20 03:25:1952 GURL request = GURL(chrome::kChromeUIFileiconURL).Resolve(path);
53 for (net::QueryIterator it(request); !it.IsAtEnd(); it.Advance()) {
54 std::string key = it.GetKey();
55 if (key == kPathParameter) {
56 *file_path = base::FilePath::FromUTF8Unsafe(it.GetUnescapedValue())
57 .NormalizePathSeparators();
58 } else if (key == kIconSizeParameter) {
59 *icon_size = SizeStringToIconSize(it.GetValue());
60 } else if (key == kScaleFactorParameter) {
61 webui::ParseScaleFactor(it.GetValue(), scale_factor);
62 }
[email protected]25cc7502012-01-31 19:33:5563 }
[email protected]25cc7502012-01-31 19:33:5564}
65
66} // namespace
[email protected]12e14fc2009-02-19 22:25:2267
danakjf4b9e942019-11-29 15:43:0468FileIconSource::IconRequestDetails::IconRequestDetails() = default;
vmpstrb8aacbe2016-02-26 02:00:4869FileIconSource::IconRequestDetails::IconRequestDetails(
danakjf4b9e942019-11-29 15:43:0470 IconRequestDetails&& other) = default;
71FileIconSource::IconRequestDetails& FileIconSource::IconRequestDetails::
72operator=(IconRequestDetails&& other) = default;
73FileIconSource::IconRequestDetails::~IconRequestDetails() = default;
vmpstrb8aacbe2016-02-26 02:00:4874
danakjf4b9e942019-11-29 15:43:0475FileIconSource::FileIconSource() = default;
76FileIconSource::~FileIconSource() = default;
[email protected]12e14fc2009-02-19 22:25:2277
[email protected]90d9f1e2013-01-16 02:46:4178void FileIconSource::FetchFileIcon(
[email protected]650b2d52013-02-10 03:41:4579 const base::FilePath& path,
[email protected]33cff1d2014-05-21 16:05:4880 float scale_factor,
[email protected]90d9f1e2013-01-16 02:46:4181 IconLoader::IconSize icon_size,
danakjf4b9e942019-11-29 15:43:0482 content::URLDataSource::GotDataCallback callback) {
[email protected]66171ab2011-03-03 15:50:0783 IconManager* im = g_browser_process->icon_manager();
[email protected]bc0147b2013-04-03 20:50:5984 gfx::Image* icon = im->LookupIconFromFilepath(path, icon_size);
[email protected]12e14fc2009-02-19 22:25:2285
86 if (icon) {
[email protected]ebbccb952012-04-20 09:51:3187 scoped_refptr<base::RefCountedBytes> icon_data(new base::RefCountedBytes);
[email protected]daf19c52012-07-13 19:01:3288 gfx::PNGCodec::EncodeBGRASkBitmap(
Malay Keshave8c63be2018-10-02 00:12:2489 icon->ToImageSkia()->GetRepresentation(scale_factor).GetBitmap(), false,
[email protected]33cff1d2014-05-21 16:05:4890 &icon_data->data());
[email protected]12e14fc2009-02-19 22:25:2291
danakjf4b9e942019-11-29 15:43:0492 std::move(callback).Run(icon_data.get());
[email protected]12e14fc2009-02-19 22:25:2293 } else {
[email protected]12e14fc2009-02-19 22:25:2294 // Attach the ChromeURLDataManager request ID to the history request.
[email protected]daf19c52012-07-13 19:01:3295 IconRequestDetails details;
danakjf4b9e942019-11-29 15:43:0496 details.callback = std::move(callback);
[email protected]daf19c52012-07-13 19:01:3297 details.scale_factor = scale_factor;
[email protected]c1896982012-12-05 20:26:1798
99 // Icon was not in cache, go fetch it slowly.
danakjf4b9e942019-11-29 15:43:04100 im->LoadIcon(path, icon_size,
101 base::BindOnce(&FileIconSource::OnFileIconDataAvailable,
102 base::Unretained(this), std::move(details)),
[email protected]c1896982012-12-05 20:26:17103 &cancelable_task_tracker_);
[email protected]12e14fc2009-02-19 22:25:22104 }
105}
106
Lucas Furukawa Gadani4b4eed02019-06-04 23:12:04107std::string FileIconSource::GetSource() {
[email protected]92253622013-01-14 20:40:50108 return kFileIconPath;
109}
110
[email protected]90d9f1e2013-01-16 02:46:41111void FileIconSource::StartDataRequest(
Wei-Yin Chen (陳威尹)39f4ff32019-10-22 17:59:09112 const GURL& url,
John Abd-El-Malek92bf3602019-07-31 02:25:48113 const content::WebContents::Getter& wc_getter,
danakjf4b9e942019-11-29 15:43:04114 content::URLDataSource::GotDataCallback callback) {
Wei-Yin Chen (陳威尹)39f4ff32019-10-22 17:59:09115 const std::string path = content::URLDataSource::URLToRequestPath(url);
[email protected]650b2d52013-02-10 03:41:45116 base::FilePath file_path;
Dan Beamb0dba212019-04-20 03:25:19117 IconLoader::IconSize icon_size = IconLoader::NORMAL;
[email protected]33cff1d2014-05-21 16:05:48118 float scale_factor = 1.0f;
Wei-Yin Chen (陳威尹)39f4ff32019-10-22 17:59:09119 // TODO(crbug/1009127): Make ParseQueryParams take GURL.
Dan Beamb0dba212019-04-20 03:25:19120 ParseQueryParams(path, &file_path, &scale_factor, &icon_size);
danakjf4b9e942019-11-29 15:43:04121 FetchFileIcon(file_path, scale_factor, icon_size, std::move(callback));
[email protected]25cc7502012-01-31 19:33:55122}
123
Lucas Furukawa Gadani4b4eed02019-06-04 23:12:04124std::string FileIconSource::GetMimeType(const std::string&) {
[email protected]e4be2dd2010-12-14 00:44:39125 // Rely on image decoder inferring the correct type.
126 return std::string();
127}
128
Lucas Furukawa Gadani4b4eed02019-06-04 23:12:04129bool FileIconSource::AllowCaching() {
treibc782ea52017-01-25 13:24:40130 return false;
131}
132
danakjf4b9e942019-11-29 15:43:04133void FileIconSource::OnFileIconDataAvailable(IconRequestDetails details,
Dana Friedfa14d5f2019-04-21 20:49:36134 gfx::Image icon) {
135 if (!icon.IsEmpty()) {
[email protected]ebbccb952012-04-20 09:51:31136 scoped_refptr<base::RefCountedBytes> icon_data(new base::RefCountedBytes);
[email protected]daf19c52012-07-13 19:01:32137 gfx::PNGCodec::EncodeBGRASkBitmap(
Dana Friedfa14d5f2019-04-21 20:49:36138 icon.ToImageSkia()->GetRepresentation(details.scale_factor).GetBitmap(),
Malay Keshave8c63be2018-10-02 00:12:24139 false, &icon_data->data());
[email protected]12e14fc2009-02-19 22:25:22140
danakjf4b9e942019-11-29 15:43:04141 std::move(details.callback).Run(icon_data.get());
[email protected]12e14fc2009-02-19 22:25:22142 } else {
143 // TODO(glen): send a dummy icon.
danakjf4b9e942019-11-29 15:43:04144 std::move(details.callback).Run(nullptr);
[email protected]12e14fc2009-02-19 22:25:22145 }
[email protected]f0a51fb52009-03-05 12:46:38146}