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/app_list/extension_app_item.h" | 5 #include "chrome/browser/ui/app_list/extension_app_item.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/metrics/user_metrics.h" | 10 #include "base/metrics/user_metrics.h" |
11 #include "build/build_config.h" | 11 #include "build/build_config.h" |
| 12 #include "chrome/browser/chromeos/extensions/gfx_utils.h" |
| 13 #include "chrome/browser/extensions/extension_app_icon.h" |
| 14 #include "chrome/browser/extensions/extension_app_icon_service.h" |
12 #include "chrome/browser/extensions/extension_util.h" | 15 #include "chrome/browser/extensions/extension_util.h" |
13 #include "chrome/browser/extensions/launch_util.h" | 16 #include "chrome/browser/extensions/launch_util.h" |
14 #include "chrome/browser/profiles/profile.h" | 17 #include "chrome/browser/profiles/profile.h" |
15 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" | 18 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h" |
16 #include "chrome/browser/ui/app_list/extension_app_context_menu.h" | 19 #include "chrome/browser/ui/app_list/extension_app_context_menu.h" |
17 #include "chrome/browser/ui/extensions/extension_enable_flow.h" | 20 #include "chrome/browser/ui/extensions/extension_enable_flow.h" |
18 #include "chrome/common/extensions/extension_constants.h" | 21 #include "chrome/common/extensions/extension_constants.h" |
19 #include "chrome/common/extensions/extension_metrics.h" | 22 #include "chrome/common/extensions/extension_metrics.h" |
20 #include "chrome/grit/theme_resources.h" | 23 #include "chrome/grit/theme_resources.h" |
21 #include "components/prefs/pref_service.h" | 24 #include "components/prefs/pref_service.h" |
22 #include "components/sync/model/string_ordinal.h" | 25 #include "components/sync/model/string_ordinal.h" |
23 #include "extensions/browser/app_sorting.h" | 26 #include "extensions/browser/app_sorting.h" |
24 #include "extensions/browser/extension_prefs.h" | 27 #include "extensions/browser/extension_prefs.h" |
25 #include "extensions/browser/extension_registry.h" | 28 #include "extensions/browser/extension_registry.h" |
26 #include "extensions/common/extension.h" | 29 #include "extensions/common/extension.h" |
27 #include "extensions/common/extension_icon_set.h" | 30 #include "extensions/common/extension_icon_set.h" |
28 #include "extensions/common/manifest_handlers/icons_handler.h" | 31 #include "extensions/common/manifest_handlers/icons_handler.h" |
29 #include "extensions/common/manifest_url_handlers.h" | 32 #include "extensions/common/manifest_url_handlers.h" |
30 #include "ui/base/resource/resource_bundle.h" | 33 #include "ui/base/resource/resource_bundle.h" |
31 #include "ui/events/event_constants.h" | 34 #include "ui/events/event_constants.h" |
32 #include "ui/gfx/canvas.h" | 35 #include "ui/gfx/canvas.h" |
33 #include "ui/gfx/geometry/rect.h" | 36 #include "ui/gfx/geometry/rect.h" |
34 #include "ui/gfx/image/canvas_image_source.h" | 37 #include "ui/gfx/image/canvas_image_source.h" |
35 #include "ui/gfx/skia_util.h" | 38 #include "ui/gfx/skia_util.h" |
36 #include "chrome/browser/chromeos/extensions/gfx_utils.h" | |
37 | 39 |
38 using extensions::Extension; | 40 using extensions::Extension; |
39 | 41 |
40 namespace { | |
41 | |
42 // Overlays a shortcut icon over the bottom left corner of a given image. | |
43 class ShortcutOverlayImageSource : public gfx::CanvasImageSource { | |
44 public: | |
45 explicit ShortcutOverlayImageSource(const gfx::ImageSkia& icon) | |
46 : gfx::CanvasImageSource(icon.size(), false), | |
47 icon_(icon) { | |
48 } | |
49 ~ShortcutOverlayImageSource() override {} | |
50 | |
51 private: | |
52 // gfx::CanvasImageSource overrides: | |
53 void Draw(gfx::Canvas* canvas) override { | |
54 canvas->DrawImageInt(icon_, 0, 0); | |
55 | |
56 // Draw the overlay in the bottom left corner of the icon. | |
57 const gfx::ImageSkia& overlay = *ui::ResourceBundle::GetSharedInstance(). | |
58 GetImageSkiaNamed(IDR_APP_LIST_TAB_OVERLAY); | |
59 canvas->DrawImageInt(overlay, 0, icon_.height() - overlay.height()); | |
60 } | |
61 | |
62 gfx::ImageSkia icon_; | |
63 | |
64 DISALLOW_COPY_AND_ASSIGN(ShortcutOverlayImageSource); | |
65 }; | |
66 | |
67 // Rounds the corners of a given image. | |
68 class RoundedCornersImageSource : public gfx::CanvasImageSource { | |
69 public: | |
70 explicit RoundedCornersImageSource(const gfx::ImageSkia& icon) | |
71 : gfx::CanvasImageSource(icon.size(), false), | |
72 icon_(icon) { | |
73 } | |
74 ~RoundedCornersImageSource() override {} | |
75 | |
76 private: | |
77 // gfx::CanvasImageSource overrides: | |
78 void Draw(gfx::Canvas* canvas) override { | |
79 // The radius used to round the app icon. | |
80 const size_t kRoundingRadius = 2; | |
81 | |
82 canvas->DrawImageInt(icon_, 0, 0); | |
83 | |
84 cc::PaintFlags masking_flags; | |
85 masking_flags.setBlendMode(SkBlendMode::kDstIn); | |
86 canvas->SaveLayerWithFlags(masking_flags); | |
87 | |
88 cc::PaintFlags mask_flags; | |
89 mask_flags.setAntiAlias(true); | |
90 mask_flags.setColor(SK_ColorWHITE); | |
91 canvas->DrawRoundRect(gfx::Rect(icon_.width(), icon_.height()), | |
92 kRoundingRadius, mask_flags); | |
93 | |
94 canvas->Restore(); | |
95 } | |
96 | |
97 gfx::ImageSkia icon_; | |
98 | |
99 DISALLOW_COPY_AND_ASSIGN(RoundedCornersImageSource); | |
100 }; | |
101 | |
102 } // namespace | |
103 | |
104 ExtensionAppItem::ExtensionAppItem( | 42 ExtensionAppItem::ExtensionAppItem( |
105 Profile* profile, | 43 Profile* profile, |
106 const app_list::AppListSyncableService::SyncItem* sync_item, | 44 const app_list::AppListSyncableService::SyncItem* sync_item, |
107 const std::string& extension_id, | 45 const std::string& extension_id, |
108 const std::string& extension_name, | 46 const std::string& extension_name, |
109 const gfx::ImageSkia& installing_icon, | 47 const gfx::ImageSkia& installing_icon, |
110 bool is_platform_app) | 48 bool is_platform_app) |
111 : ChromeAppListItem(profile, extension_id), | 49 : ChromeAppListItem(profile, extension_id), |
112 extension_enable_flow_controller_(NULL), | 50 extension_enable_flow_controller_(NULL), |
113 extension_name_(extension_name), | 51 extension_name_(extension_name), |
114 installing_icon_(CreateDisabledIcon(installing_icon)), | 52 installing_icon_(CreateDisabledIcon(installing_icon)), |
115 is_platform_app_(is_platform_app) { | 53 is_platform_app_(is_platform_app) { |
116 Reload(); | 54 Reload(); |
117 if (sync_item && sync_item->item_ordinal.IsValid()) | 55 if (sync_item && sync_item->item_ordinal.IsValid()) |
118 UpdateFromSync(sync_item); | 56 UpdateFromSync(sync_item); |
119 else | 57 else |
120 SetDefaultPositionIfApplicable(); | 58 SetDefaultPositionIfApplicable(); |
121 } | 59 } |
122 | 60 |
123 ExtensionAppItem::~ExtensionAppItem() { | 61 ExtensionAppItem::~ExtensionAppItem() { |
124 } | 62 } |
125 | 63 |
126 void ExtensionAppItem::Reload() { | 64 void ExtensionAppItem::Reload() { |
127 const Extension* extension = GetExtension(); | 65 const Extension* extension = GetExtension(); |
128 bool is_installing = !extension; | 66 bool is_installing = !extension; |
129 SetIsInstalling(is_installing); | 67 SetIsInstalling(is_installing); |
130 if (is_installing) { | 68 if (is_installing) { |
131 SetName(extension_name_); | 69 SetName(extension_name_); |
132 UpdateIcon(); | 70 SetIcon(installing_icon_); |
133 return; | 71 return; |
134 } | 72 } |
135 SetNameAndShortName(extension->name(), extension->short_name()); | 73 SetNameAndShortName(extension->name(), extension->short_name()); |
136 LoadImage(extension); | 74 if (!icon_) { |
| 75 icon_ = extensions::ExtensionAppIconService::Get(profile())->CreateIcon( |
| 76 this, extension_id(), extension_misc::EXTENSION_ICON_MEDIUM); |
| 77 } else { |
| 78 icon_->Reload(); |
| 79 } |
137 } | 80 } |
138 | 81 |
139 void ExtensionAppItem::UpdateIcon() { | 82 void ExtensionAppItem::OnIconUpdated(extensions::ExtensionAppIcon* icon) { |
140 gfx::ImageSkia icon = installing_icon_; | 83 SetIcon(icon->IsValid() ? icon->image_skia() : installing_icon_); |
141 | |
142 // Use the app icon if the app exists. Turn the image greyscale if the app is | |
143 // not launchable. | |
144 if (GetExtension() && icon_) { | |
145 icon = icon_->image_skia(); | |
146 const bool enabled = extensions::util::IsAppLaunchable(extension_id(), | |
147 profile()); | |
148 extensions::util::MaybeApplyChromeBadge(profile(), id(), &icon); | |
149 | |
150 if (!enabled) | |
151 icon = CreateDisabledIcon(icon); | |
152 | |
153 if (GetExtension()->from_bookmark()) | |
154 icon = gfx::ImageSkia(new RoundedCornersImageSource(icon), icon.size()); | |
155 } | |
156 SetIcon(icon); | |
157 } | 84 } |
158 | 85 |
159 const Extension* ExtensionAppItem::GetExtension() const { | 86 const Extension* ExtensionAppItem::GetExtension() const { |
160 const extensions::ExtensionRegistry* registry = | 87 const extensions::ExtensionRegistry* registry = |
161 extensions::ExtensionRegistry::Get(profile()); | 88 extensions::ExtensionRegistry::Get(profile()); |
162 const Extension* extension = registry->GetInstalledExtension( | 89 const Extension* extension = registry->GetInstalledExtension( |
163 extension_id()); | 90 extension_id()); |
164 return extension; | 91 return extension; |
165 } | 92 } |
166 | 93 |
167 void ExtensionAppItem::LoadImage(const Extension* extension) { | |
168 icon_.reset(new extensions::IconImage( | |
169 profile(), | |
170 extension, | |
171 extensions::IconsInfo::GetIcons(extension), | |
172 extension_misc::EXTENSION_ICON_MEDIUM, | |
173 extensions::util::GetDefaultAppIcon(), | |
174 this)); | |
175 UpdateIcon(); | |
176 } | |
177 | |
178 bool ExtensionAppItem::RunExtensionEnableFlow() { | 94 bool ExtensionAppItem::RunExtensionEnableFlow() { |
179 if (extensions::util::IsAppLaunchableWithoutEnabling(extension_id(), | 95 if (extensions::util::IsAppLaunchableWithoutEnabling(extension_id(), |
180 profile())) | 96 profile())) |
181 return false; | 97 return false; |
182 | 98 |
183 if (!extension_enable_flow_) { | 99 if (!extension_enable_flow_) { |
184 extension_enable_flow_controller_ = GetController(); | 100 extension_enable_flow_controller_ = GetController(); |
185 extension_enable_flow_controller_->OnShowChildDialog(); | 101 extension_enable_flow_controller_->OnShowChildDialog(); |
186 | 102 |
187 extension_enable_flow_.reset(new ExtensionEnableFlow( | 103 extension_enable_flow_.reset(new ExtensionEnableFlow( |
(...skipping 16 matching lines...) Expand all Loading... |
204 | 120 |
205 if (RunExtensionEnableFlow()) | 121 if (RunExtensionEnableFlow()) |
206 return; | 122 return; |
207 | 123 |
208 GetController()->LaunchApp(profile(), | 124 GetController()->LaunchApp(profile(), |
209 extension, | 125 extension, |
210 AppListControllerDelegate::LAUNCH_FROM_APP_LIST, | 126 AppListControllerDelegate::LAUNCH_FROM_APP_LIST, |
211 event_flags); | 127 event_flags); |
212 } | 128 } |
213 | 129 |
214 void ExtensionAppItem::OnExtensionIconImageChanged( | |
215 extensions::IconImage* image) { | |
216 DCHECK(icon_.get() == image); | |
217 UpdateIcon(); | |
218 } | |
219 | |
220 void ExtensionAppItem::OnExtensionIconImageDestroyed( | |
221 extensions::IconImage* image) { | |
222 SetIcon(gfx::ImageSkia()); | |
223 } | |
224 | |
225 void ExtensionAppItem::ExtensionEnableFlowFinished() { | 130 void ExtensionAppItem::ExtensionEnableFlowFinished() { |
226 extension_enable_flow_.reset(); | 131 extension_enable_flow_.reset(); |
227 extension_enable_flow_controller_->OnCloseChildDialog(); | 132 extension_enable_flow_controller_->OnCloseChildDialog(); |
228 extension_enable_flow_controller_ = NULL; | 133 extension_enable_flow_controller_ = NULL; |
229 | 134 |
230 // Automatically launch app after enabling. | 135 // Automatically launch app after enabling. |
231 Launch(ui::EF_NONE); | 136 Launch(ui::EF_NONE); |
232 } | 137 } |
233 | 138 |
234 void ExtensionAppItem::ExtensionEnableFlowAborted(bool user_initiated) { | 139 void ExtensionAppItem::ExtensionEnableFlowAborted(bool user_initiated) { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 // static | 175 // static |
271 const char ExtensionAppItem::kItemType[] = "ExtensionAppItem"; | 176 const char ExtensionAppItem::kItemType[] = "ExtensionAppItem"; |
272 | 177 |
273 const char* ExtensionAppItem::GetItemType() const { | 178 const char* ExtensionAppItem::GetItemType() const { |
274 return ExtensionAppItem::kItemType; | 179 return ExtensionAppItem::kItemType; |
275 } | 180 } |
276 | 181 |
277 void ExtensionAppItem::ExecuteLaunchCommand(int event_flags) { | 182 void ExtensionAppItem::ExecuteLaunchCommand(int event_flags) { |
278 Launch(event_flags); | 183 Launch(event_flags); |
279 } | 184 } |
OLD | NEW |