OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/extensions/api/developer_private/extension_info_generat or.h" | 5 #include "chrome/browser/extensions/api/developer_private/extension_info_generat or.h" |
6 | 6 |
7 #include "base/base64.h" | |
7 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
8 #include "chrome/browser/extensions/api/developer_private/inspectable_views_find er.h" | 9 #include "chrome/browser/extensions/api/developer_private/inspectable_views_find er.h" |
9 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" | 10 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" |
10 #include "chrome/browser/extensions/error_console/error_console.h" | 11 #include "chrome/browser/extensions/error_console/error_console.h" |
11 #include "chrome/browser/extensions/extension_service.h" | 12 #include "chrome/browser/extensions/extension_service.h" |
12 #include "chrome/browser/extensions/extension_ui_util.h" | 13 #include "chrome/browser/extensions/extension_ui_util.h" |
13 #include "chrome/browser/extensions/extension_util.h" | 14 #include "chrome/browser/extensions/extension_util.h" |
14 #include "chrome/browser/extensions/path_util.h" | 15 #include "chrome/browser/extensions/path_util.h" |
15 #include "chrome/browser/extensions/shared_module_service.h" | 16 #include "chrome/browser/extensions/shared_module_service.h" |
16 #include "chrome/browser/profiles/profile.h" | 17 #include "chrome/browser/profiles/profile.h" |
17 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" | 18 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" |
18 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" | 19 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" |
19 #include "chrome/grit/generated_resources.h" | 20 #include "chrome/grit/generated_resources.h" |
20 #include "content/public/browser/render_view_host.h" | 21 #include "content/public/browser/render_view_host.h" |
21 #include "extensions/browser/extension_error.h" | 22 #include "extensions/browser/extension_error.h" |
22 #include "extensions/browser/extension_prefs.h" | 23 #include "extensions/browser/extension_prefs.h" |
23 #include "extensions/browser/extension_registry.h" | 24 #include "extensions/browser/extension_registry.h" |
24 #include "extensions/browser/extension_system.h" | 25 #include "extensions/browser/extension_system.h" |
26 #include "extensions/browser/image_loader.h" | |
25 #include "extensions/browser/warning_service.h" | 27 #include "extensions/browser/warning_service.h" |
26 #include "extensions/common/extension_set.h" | 28 #include "extensions/common/extension_set.h" |
27 #include "extensions/common/feature_switch.h" | 29 #include "extensions/common/feature_switch.h" |
28 #include "extensions/common/install_warning.h" | 30 #include "extensions/common/install_warning.h" |
29 #include "extensions/common/manifest.h" | 31 #include "extensions/common/manifest.h" |
30 #include "extensions/common/manifest_handlers/background_info.h" | 32 #include "extensions/common/manifest_handlers/background_info.h" |
33 #include "extensions/common/manifest_handlers/icons_handler.h" | |
31 #include "extensions/common/manifest_handlers/offline_enabled_info.h" | 34 #include "extensions/common/manifest_handlers/offline_enabled_info.h" |
32 #include "extensions/common/manifest_handlers/options_page_info.h" | 35 #include "extensions/common/manifest_handlers/options_page_info.h" |
33 #include "extensions/common/manifest_url_handlers.h" | 36 #include "extensions/common/manifest_url_handlers.h" |
34 #include "extensions/common/permissions/permissions_data.h" | 37 #include "extensions/common/permissions/permissions_data.h" |
38 #include "extensions/grit/extensions_browser_resources.h" | |
35 #include "ui/base/l10n/l10n_util.h" | 39 #include "ui/base/l10n/l10n_util.h" |
40 #include "ui/base/resource/resource_bundle.h" | |
41 #include "ui/gfx/codec/png_codec.h" | |
42 #include "ui/gfx/color_utils.h" | |
43 #include "ui/gfx/image/image.h" | |
44 #include "ui/gfx/skbitmap_operations.h" | |
36 | 45 |
37 namespace extensions { | 46 namespace extensions { |
38 | 47 |
39 namespace developer = api::developer_private; | 48 namespace developer = api::developer_private; |
40 | 49 |
41 namespace { | 50 namespace { |
42 | 51 |
43 // Given a Manifest::Type, converts it into its developer_private | 52 // Given a Manifest::Type, converts it into its developer_private |
44 // counterpart. | 53 // counterpart. |
45 developer::ExtensionType GetExtensionType(Manifest::Type manifest_type) { | 54 developer::ExtensionType GetExtensionType(Manifest::Type manifest_type) { |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
135 | 144 |
136 } // namespace | 145 } // namespace |
137 | 146 |
138 ExtensionInfoGenerator::ExtensionInfoGenerator( | 147 ExtensionInfoGenerator::ExtensionInfoGenerator( |
139 content::BrowserContext* browser_context) | 148 content::BrowserContext* browser_context) |
140 : browser_context_(browser_context), | 149 : browser_context_(browser_context), |
141 extension_system_(ExtensionSystem::Get(browser_context)), | 150 extension_system_(ExtensionSystem::Get(browser_context)), |
142 extension_prefs_(ExtensionPrefs::Get(browser_context)), | 151 extension_prefs_(ExtensionPrefs::Get(browser_context)), |
143 extension_action_api_(ExtensionActionAPI::Get(browser_context)), | 152 extension_action_api_(ExtensionActionAPI::Get(browser_context)), |
144 warning_service_(WarningService::Get(browser_context)), | 153 warning_service_(WarningService::Get(browser_context)), |
145 error_console_(ErrorConsole::Get(browser_context)) { | 154 error_console_(ErrorConsole::Get(browser_context)), |
155 image_loader_(ImageLoader::Get(browser_context)), | |
156 pending_image_loads_(0u), | |
157 weak_factory_(this) { | |
146 } | 158 } |
147 | 159 |
148 ExtensionInfoGenerator::~ExtensionInfoGenerator() { | 160 ExtensionInfoGenerator::~ExtensionInfoGenerator() { |
149 } | 161 } |
150 | 162 |
151 scoped_ptr<developer::ExtensionInfo> | 163 void ExtensionInfoGenerator::CreateExtensionInfo( |
152 ExtensionInfoGenerator::CreateExtensionInfo(const Extension& extension, | 164 const std::string& id, |
153 developer::ExtensionState state) { | 165 const ExtensionInfosCallback& callback) { |
166 callback_ = callback; | |
167 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_); | |
168 | |
169 developer::ExtensionState state = developer::EXTENSION_STATE_NONE; | |
170 const Extension* ext = nullptr; | |
171 if ((ext = registry->enabled_extensions().GetByID(id)) != nullptr) | |
172 state = developer::EXTENSION_STATE_ENABLED; | |
173 else if ((ext = registry->disabled_extensions().GetByID(id)) != nullptr) | |
174 state = developer::EXTENSION_STATE_DISABLED; | |
175 else if ((ext = registry->terminated_extensions().GetByID(id)) != nullptr) | |
176 state = developer::EXTENSION_STATE_TERMINATED; | |
177 | |
178 if (ext && ui_util::ShouldDisplayInExtensionSettings(ext, browser_context_)) | |
179 CreateExtensionInfoHelper(*ext, state); | |
180 | |
181 if (pending_image_loads_ == 0) { | |
182 // Don't call the callback re-entrantly. | |
183 base::MessageLoop::current()->PostTask(FROM_HERE, | |
184 base::Bind(callback, list_)); | |
185 } else { | |
186 callback_ = callback; | |
not at google - send to devlin
2015/04/22 21:38:37
You already assigned on line 166?
Devlin
2015/04/23 19:17:21
Whoops! I don't want to.
| |
187 } | |
188 } | |
189 | |
190 void ExtensionInfoGenerator::CreateExtensionsInfo( | |
191 bool include_disabled, | |
192 bool include_terminated, | |
193 const ExtensionInfosCallback& callback) { | |
194 callback_ = callback; | |
195 auto add_to_list = [this](const ExtensionSet& extensions, | |
196 developer::ExtensionState state) { | |
197 for (const scoped_refptr<const Extension>& extension : extensions) { | |
198 if (ui_util::ShouldDisplayInExtensionSettings(extension.get(), | |
199 browser_context_)) { | |
200 CreateExtensionInfoHelper(*extension, state); | |
201 } | |
202 } | |
203 }; | |
204 | |
205 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_); | |
206 add_to_list(registry->enabled_extensions(), | |
207 developer::EXTENSION_STATE_ENABLED); | |
208 if (include_disabled) { | |
209 add_to_list(registry->disabled_extensions(), | |
210 developer::EXTENSION_STATE_DISABLED); | |
211 } | |
212 if (include_terminated) { | |
213 add_to_list(registry->terminated_extensions(), | |
214 developer::EXTENSION_STATE_TERMINATED); | |
215 } | |
216 | |
217 if (pending_image_loads_ == 0) { | |
218 // Don't call the callback re-entrantly. | |
219 base::MessageLoop::current()->PostTask(FROM_HERE, | |
220 base::Bind(callback, list_)); | |
221 } else { | |
222 callback_ = callback; | |
not at google - send to devlin
2015/04/22 21:38:37
(ditto)
Devlin
2015/04/23 19:17:21
Done.
| |
223 } | |
224 } | |
225 | |
226 void ExtensionInfoGenerator::CreateExtensionInfoHelper( | |
227 const Extension& extension, | |
228 developer::ExtensionState state) { | |
154 scoped_ptr<developer::ExtensionInfo> info(new developer::ExtensionInfo()); | 229 scoped_ptr<developer::ExtensionInfo> info(new developer::ExtensionInfo()); |
155 | 230 |
156 // Don't consider the button hidden with the redesign, because "hidden" | 231 // Don't consider the button hidden with the redesign, because "hidden" |
157 // buttons are now just hidden in the wrench menu. | 232 // buttons are now just hidden in the wrench menu. |
158 info->action_button_hidden = | 233 info->action_button_hidden = |
159 !extension_action_api_->GetBrowserActionVisibility(extension.id()) && | 234 !extension_action_api_->GetBrowserActionVisibility(extension.id()) && |
160 !FeatureSwitch::extension_action_redesign()->IsEnabled(); | 235 !FeatureSwitch::extension_action_redesign()->IsEnabled(); |
161 | 236 |
162 // Blacklist text. | 237 // Blacklist text. |
163 int blacklist_text = -1; | 238 int blacklist_text = -1; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
210 | 285 |
211 // File access. | 286 // File access. |
212 info->file_access.is_enabled = extension.wants_file_access(); | 287 info->file_access.is_enabled = extension.wants_file_access(); |
213 info->file_access.is_active = | 288 info->file_access.is_active = |
214 util::AllowFileAccess(extension.id(), browser_context_); | 289 util::AllowFileAccess(extension.id(), browser_context_); |
215 | 290 |
216 // Home page. | 291 // Home page. |
217 info->home_page.url = ManifestURL::GetHomepageURL(&extension).spec(); | 292 info->home_page.url = ManifestURL::GetHomepageURL(&extension).spec(); |
218 info->home_page.specified = ManifestURL::SpecifiedHomepageURL(&extension); | 293 info->home_page.specified = ManifestURL::SpecifiedHomepageURL(&extension); |
219 | 294 |
220 bool is_enabled = state == developer::EXTENSION_STATE_ENABLED; | |
221 | |
222 // TODO(devlin): This won't work with apps (CORS). We should convert to data | |
223 // urls. | |
224 info->icon_url = | |
225 ExtensionIconSource::GetIconURL(&extension, | |
226 extension_misc::EXTENSION_ICON_MEDIUM, | |
227 ExtensionIconSet::MATCH_BIGGER, | |
228 !is_enabled, | |
229 nullptr).spec(); | |
230 | |
231 info->id = extension.id(); | 295 info->id = extension.id(); |
232 | 296 |
233 // Incognito access. | 297 // Incognito access. |
234 info->incognito_access.is_enabled = extension.can_be_incognito_enabled(); | 298 info->incognito_access.is_enabled = extension.can_be_incognito_enabled(); |
235 info->incognito_access.is_active = | 299 info->incognito_access.is_active = |
236 util::IsIncognitoEnabled(extension.id(), browser_context_); | 300 util::IsIncognitoEnabled(extension.id(), browser_context_); |
237 | 301 |
238 Profile* profile = Profile::FromBrowserContext(browser_context_); | 302 Profile* profile = Profile::FromBrowserContext(browser_context_); |
239 info->installed_by_custodian = | 303 info->installed_by_custodian = |
240 util::IsExtensionSupervised(&extension, profile); | 304 util::IsExtensionSupervised(&extension, profile); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
350 | 414 |
351 info->type = GetExtensionType(extension.manifest()->type()); | 415 info->type = GetExtensionType(extension.manifest()->type()); |
352 | 416 |
353 info->update_url = ManifestURL::GetUpdateURL(&extension).spec(); | 417 info->update_url = ManifestURL::GetUpdateURL(&extension).spec(); |
354 | 418 |
355 info->user_may_modify = | 419 info->user_may_modify = |
356 management_policy->UserMayModifySettings(&extension, nullptr); | 420 management_policy->UserMayModifySettings(&extension, nullptr); |
357 | 421 |
358 info->version = extension.GetVersionForDisplay(); | 422 info->version = extension.GetVersionForDisplay(); |
359 | 423 |
424 bool is_enabled = state == developer::EXTENSION_STATE_ENABLED; | |
360 if (state != developer::EXTENSION_STATE_TERMINATED) { | 425 if (state != developer::EXTENSION_STATE_TERMINATED) { |
361 info->views = InspectableViewsFinder(profile). | 426 info->views = InspectableViewsFinder(profile). |
362 GetViewsForExtension(extension, is_enabled); | 427 GetViewsForExtension(extension, is_enabled); |
363 } | 428 } |
364 return info.Pass(); | 429 |
430 // The icon. | |
431 ExtensionResource icon = | |
432 IconsInfo::GetIconResource(&extension, | |
433 extension_misc::EXTENSION_ICON_MEDIUM, | |
434 ExtensionIconSet::MATCH_BIGGER); | |
435 if (icon.empty()) { | |
436 info->icon_url = GetDefaultIconUrl(extension.is_app(), !is_enabled); | |
437 list_.push_back(make_linked_ptr(info.release())); | |
438 } else { | |
439 ++pending_image_loads_; | |
440 image_loader_->LoadImageAsync( | |
441 &extension, | |
442 icon, | |
443 gfx::Size(128, 128), | |
not at google - send to devlin
2015/04/22 21:38:37
Where does 128/128 come from?
Devlin
2015/04/23 19:17:21
Added a comment.
not at google - send to devlin
2015/04/23 22:25:21
I presume you meant to use max_size here.
Devlin
2015/04/27 17:06:30
Done.
| |
444 base::Bind(&ExtensionInfoGenerator::OnImageLoaded, | |
445 weak_factory_.GetWeakPtr(), | |
446 base::Passed(info.Pass()))); | |
447 } | |
365 } | 448 } |
366 | 449 |
367 scoped_ptr<api::developer_private::ExtensionInfo> | 450 const std::string& ExtensionInfoGenerator::GetDefaultIconUrl( |
368 ExtensionInfoGenerator::CreateExtensionInfo(const std::string& id) { | 451 bool is_app, |
369 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_); | 452 bool is_greyscale) { |
370 | 453 std::string* str; |
371 const Extension* enabled = registry->enabled_extensions().GetByID(id); | 454 if (is_app) { |
372 if (enabled && | 455 str = is_greyscale ? &default_disabled_app_icon_url_ : |
373 ui_util::ShouldDisplayInExtensionSettings(enabled, browser_context_)) { | 456 &default_app_icon_url_; |
374 return CreateExtensionInfo(*enabled, developer::EXTENSION_STATE_ENABLED); | 457 } else { |
458 str = is_greyscale ? &default_disabled_extension_icon_url_ : | |
459 &default_extension_icon_url_; | |
375 } | 460 } |
376 | 461 |
377 const Extension* disabled = registry->disabled_extensions().GetByID(id); | 462 if (str->empty()) { |
378 if (disabled && | 463 *str = GetIconUrlFromImage( |
379 ui_util::ShouldDisplayInExtensionSettings(disabled, browser_context_)) { | 464 ui::ResourceBundle::GetSharedInstance().GetImageNamed( |
380 return CreateExtensionInfo(*disabled, developer::EXTENSION_STATE_DISABLED); | 465 is_app ? IDR_APP_DEFAULT_ICON : IDR_EXTENSION_DEFAULT_ICON), |
466 is_greyscale); | |
381 } | 467 } |
382 | 468 |
383 const Extension* terminated = registry->terminated_extensions().GetByID(id); | 469 return *str; |
384 if (terminated && | 470 } |
385 ui_util::ShouldDisplayInExtensionSettings(terminated, browser_context_)) { | 471 |
386 return CreateExtensionInfo(*terminated, | 472 std::string ExtensionInfoGenerator::GetIconUrlFromImage( |
387 developer::EXTENSION_STATE_TERMINATED); | 473 const gfx::Image& image, |
474 bool should_greyscale) { | |
475 scoped_refptr<base::RefCountedMemory> data; | |
476 if (should_greyscale) { | |
477 color_utils::HSL shift = {-1, 0, 0.6}; | |
478 SkBitmap bitmap = | |
479 SkBitmapOperations::CreateHSLShiftedBitmap(*image.ToSkBitmap(), shift); | |
480 scoped_refptr<base::RefCountedBytes> image_bytes( | |
481 new base::RefCountedBytes()); | |
482 gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, false, &image_bytes->data()); | |
483 data = image_bytes; | |
484 } else { | |
485 data = image.As1xPNGBytes(); | |
388 } | 486 } |
389 | 487 |
390 return scoped_ptr<api::developer_private::ExtensionInfo>(); | 488 std::string base_64; |
489 base::Base64Encode(std::string(data->front_as<char>(), data->size()), | |
490 &base_64); | |
491 const char kDataUrlPrefix[] = "data:image/png;base64,"; | |
492 return GURL(kDataUrlPrefix + base_64).spec(); | |
391 } | 493 } |
392 | 494 |
393 ExtensionInfoGenerator::ExtensionInfoList | 495 void ExtensionInfoGenerator::OnImageLoaded( |
394 ExtensionInfoGenerator::CreateExtensionsInfo(bool include_disabled, | 496 scoped_ptr<developer::ExtensionInfo> info, |
395 bool include_terminated) { | 497 const gfx::Image& icon) { |
396 std::vector<linked_ptr<developer::ExtensionInfo>> list; | 498 info->icon_url = GetIconUrlFromImage( |
397 auto add_to_list = [this, &list](const ExtensionSet& extensions, | 499 icon, info->state != developer::EXTENSION_STATE_ENABLED); |
398 developer::ExtensionState state) { | 500 list_.push_back(make_linked_ptr(info.release())); |
399 for (const scoped_refptr<const Extension>& extension : extensions) { | |
400 if (ui_util::ShouldDisplayInExtensionSettings(extension.get(), | |
401 browser_context_)) { | |
402 scoped_ptr<developer::ExtensionInfo> info = | |
403 CreateExtensionInfo(*extension, state); | |
404 list.push_back(make_linked_ptr(info.release())); | |
405 } | |
406 } | |
407 }; | |
408 | 501 |
409 ExtensionRegistry* registry = ExtensionRegistry::Get(browser_context_); | 502 --pending_image_loads_; |
410 add_to_list(registry->enabled_extensions(), | 503 |
411 developer::EXTENSION_STATE_ENABLED); | 504 if (pending_image_loads_ == 0) { // All done! |
412 if (include_disabled) { | 505 // We assign to a temporary and Reset() so that at the end of the method, |
413 add_to_list(registry->disabled_extensions(), | 506 // any stored refs are destroyed. |
414 developer::EXTENSION_STATE_DISABLED); | 507 ExtensionInfosCallback callback = callback_; |
508 callback_.Reset(); | |
509 callback.Run(list_); | |
415 } | 510 } |
416 if (include_terminated) { | |
417 add_to_list(registry->terminated_extensions(), | |
418 developer::EXTENSION_STATE_TERMINATED); | |
419 } | |
420 | |
421 return list; | |
422 } | 511 } |
423 | 512 |
424 } // namespace extensions | 513 } // namespace extensions |
OLD | NEW |