OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/webui/theme_source.h" | 5 #include "chrome/browser/ui/webui/theme_source.h" |
6 | 6 |
7 #include "base/memory/ref_counted_memory.h" | 7 #include "base/memory/ref_counted_memory.h" |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "chrome/browser/profiles/profile.h" | 10 #include "chrome/browser/profiles/profile.h" |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 | 85 |
86 void ThemeSource::StartDataRequest( | 86 void ThemeSource::StartDataRequest( |
87 const std::string& path, | 87 const std::string& path, |
88 int render_process_id, | 88 int render_process_id, |
89 int render_frame_id, | 89 int render_frame_id, |
90 const content::URLDataSource::GotDataCallback& callback) { | 90 const content::URLDataSource::GotDataCallback& callback) { |
91 // Default scale factor if not specified. | 91 // Default scale factor if not specified. |
92 float scale = 1.0f; | 92 float scale = 1.0f; |
93 std::string parsed_path; | 93 std::string parsed_path; |
94 webui::ParsePathAndScale(GetThemeURL(path), &parsed_path, &scale); | 94 webui::ParsePathAndScale(GetThemeURL(path), &parsed_path, &scale); |
95 scale = ui::GetScaleForScaleFactor(ui::GetSupportedScaleFactor(scale)); | |
96 | 95 |
97 if (IsNewTabCSSPath(parsed_path)) { | 96 if (IsNewTabCSSPath(parsed_path)) { |
98 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 97 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
99 callback.Run(css_bytes_.get()); | 98 callback.Run(css_bytes_.get()); |
100 return; | 99 return; |
101 } | 100 } |
102 | 101 |
103 int resource_id = -1; | 102 int resource_id = -1; |
104 if (parsed_path == "current-channel-logo") { | 103 if (parsed_path == "current-channel-logo") { |
105 switch (chrome::GetChannel()) { | 104 switch (chrome::GetChannel()) { |
(...skipping 18 matching lines...) Expand all Loading... |
124 NOTREACHED(); | 123 NOTREACHED(); |
125 #endif | 124 #endif |
126 case version_info::Channel::UNKNOWN: | 125 case version_info::Channel::UNKNOWN: |
127 resource_id = IDR_PRODUCT_LOGO_32; | 126 resource_id = IDR_PRODUCT_LOGO_32; |
128 break; | 127 break; |
129 } | 128 } |
130 } else { | 129 } else { |
131 resource_id = ResourcesUtil::GetThemeResourceId(parsed_path); | 130 resource_id = ResourcesUtil::GetThemeResourceId(parsed_path); |
132 } | 131 } |
133 | 132 |
| 133 // Limit the maximum scale we'll respond to. Very large scale factors can |
| 134 // take significant time to serve or, at worst, crash the browser due to OOM. |
| 135 // We don't want to clamp to the max scale factor, though, for devices that |
| 136 // use 2x scale without 2x data packs, as well as omnibox requests for larger |
| 137 // (but still reasonable) scales (see below). |
134 const float max_scale = ui::GetScaleForScaleFactor( | 138 const float max_scale = ui::GetScaleForScaleFactor( |
135 ResourceBundle::GetSharedInstance().GetMaxScaleFactor()); | 139 ResourceBundle::GetSharedInstance().GetMaxScaleFactor()); |
136 if (resource_id == -1) { | 140 const float unreasonable_scale = max_scale * 32; |
137 // We have no data to send back. This shouldn't happen normally, as | 141 if ((resource_id == -1) || (scale >= unreasonable_scale)) { |
138 // chrome://theme/ URLs are only used by WebUI pages and component | 142 // Either we have no data to send back, or the requested scale is |
139 // extensions. However, the user can also enter these into the omnibox, so | 143 // unreasonably large. This shouldn't happen normally, as chrome://theme/ |
140 // we need to fail gracefully. | 144 // URLs are only used by WebUI pages and component extensions. However, the |
| 145 // user can also enter these into the omnibox, so we need to fail |
| 146 // gracefully. |
141 callback.Run(nullptr); | 147 callback.Run(nullptr); |
142 } else if ((GetMimeType(path) == "image/png") && (scale > max_scale)) { | 148 } else if ((GetMimeType(path) == "image/png") && (scale > max_scale)) { |
143 SendThemeImage(callback, resource_id, scale); | 149 SendThemeImage(callback, resource_id, scale); |
144 } else { | 150 } else { |
145 SendThemeBitmap(callback, resource_id, scale); | 151 SendThemeBitmap(callback, resource_id, scale); |
146 } | 152 } |
147 } | 153 } |
148 | 154 |
149 std::string ThemeSource::GetMimeType(const std::string& path) const { | 155 std::string ThemeSource::GetMimeType(const std::string& path) const { |
150 std::string parsed_path; | 156 std::string parsed_path; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 } else { | 222 } else { |
217 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 223 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
218 // Fetching image data in ResourceBundle should happen on the UI thread. See | 224 // Fetching image data in ResourceBundle should happen on the UI thread. See |
219 // crbug.com/449277 | 225 // crbug.com/449277 |
220 content::BrowserThread::PostTaskAndReply( | 226 content::BrowserThread::PostTaskAndReply( |
221 content::BrowserThread::UI, FROM_HERE, | 227 content::BrowserThread::UI, FROM_HERE, |
222 base::Bind(&ProcessResourceOnUIThread, resource_id, scale, data), | 228 base::Bind(&ProcessResourceOnUIThread, resource_id, scale, data), |
223 base::Bind(callback, data)); | 229 base::Bind(callback, data)); |
224 } | 230 } |
225 } | 231 } |
OLD | NEW |