Upstream version 11.39.264.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / apps / app_info_dialog / app_info_header_panel.cc
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.h"
6
7 #include "base/bind.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/extensions/extension_service.h"
10 #include "chrome/browser/extensions/extension_util.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/ui/browser_navigator.h"
13 #include "chrome/common/extensions/extension_constants.h"
14 #include "chrome/common/extensions/manifest_url_handler.h"
15 #include "chrome/grit/generated_resources.h"
16 #include "extensions/browser/extension_system.h"
17 #include "extensions/browser/image_loader.h"
18 #include "extensions/common/constants.h"
19 #include "extensions/common/extension.h"
20 #include "extensions/common/extension_icon_set.h"
21 #include "extensions/common/extension_resource.h"
22 #include "extensions/common/manifest_handlers/icons_handler.h"
23 #include "extensions/common/manifest_handlers/shared_module_info.h"
24 #include "net/base/url_util.h"
25 #include "third_party/skia/include/core/SkBitmap.h"
26 #include "ui/base/l10n/l10n_util.h"
27 #include "ui/base/resource/resource_bundle.h"
28 #include "ui/gfx/geometry/size.h"
29 #include "ui/gfx/image/image.h"
30 #include "ui/gfx/image/image_skia.h"
31 #include "ui/gfx/image/image_skia_rep.h"
32 #include "ui/gfx/native_widget_types.h"
33 #include "ui/gfx/text_constants.h"
34 #include "ui/views/controls/image_view.h"
35 #include "ui/views/controls/label.h"
36 #include "ui/views/controls/link.h"
37 #include "ui/views/layout/box_layout.h"
38 #include "ui/views/layout/grid_layout.h"
39 #include "ui/views/layout/layout_constants.h"
40 #include "ui/views/view.h"
41 #include "url/gurl.h"
42
43 namespace {
44
45 // Size of extension icon in top left of dialog.
46 const int kIconSize = 64;
47
48 // The horizontal spacing between the app's links in the header section.
49 const int kSpacingBetweenAppLinks = 3;
50
51 }  // namespace
52
53 AppInfoHeaderPanel::AppInfoHeaderPanel(Profile* profile,
54                                        const extensions::Extension* app)
55     : AppInfoPanel(profile, app),
56       app_icon_(NULL),
57       app_name_label_(NULL),
58       view_in_store_link_(NULL),
59       licenses_link_(NULL),
60       weak_ptr_factory_(this) {
61   CreateControls();
62
63   SetLayoutManager(
64       new views::BoxLayout(views::BoxLayout::kHorizontal,
65                            views::kButtonHEdgeMargin,
66                            views::kButtonVEdgeMargin,
67                            views::kRelatedControlHorizontalSpacing));
68
69   LayoutControls();
70 }
71
72 AppInfoHeaderPanel::~AppInfoHeaderPanel() {
73 }
74
75 void AppInfoHeaderPanel::CreateControls() {
76   app_name_label_ =
77       new views::Label(base::UTF8ToUTF16(app_->name()),
78                        ui::ResourceBundle::GetSharedInstance().GetFontList(
79                            ui::ResourceBundle::MediumFont));
80   app_name_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
81
82   app_icon_ = new views::ImageView();
83   app_icon_->SetImageSize(gfx::Size(kIconSize, kIconSize));
84   LoadAppImageAsync();
85
86   if (CanShowAppInWebStore()) {
87     view_in_store_link_ = new views::Link(
88         l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_WEB_STORE_LINK));
89     view_in_store_link_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
90     view_in_store_link_->set_listener(this);
91   }
92
93   if (CanDisplayLicenses()) {
94     licenses_link_ = new views::Link(
95         l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_LICENSES_BUTTON_TEXT));
96     licenses_link_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
97     licenses_link_->set_listener(this);
98   }
99 }
100
101 void AppInfoHeaderPanel::LayoutControls() {
102   AddChildView(app_icon_);
103
104   // Create a vertical container to store the app's name and links.
105   views::View* vertical_info_container = new views::View();
106   views::BoxLayout* vertical_container_layout =
107       new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0);
108   vertical_container_layout->set_main_axis_alignment(
109       views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
110   vertical_info_container->SetLayoutManager(vertical_container_layout);
111   AddChildView(vertical_info_container);
112
113   vertical_info_container->AddChildView(app_name_label_);
114   if (!view_in_store_link_ && !licenses_link_) {
115     // If there's no links, allow the app's name to take up multiple lines.
116     // TODO(sashab): Limit the number of lines to 2.
117     app_name_label_->SetMultiLine(true);
118   } else {
119     // Create a horizontal container to store the app's links.
120     views::View* horizontal_links_container =
121         CreateHorizontalStack(kSpacingBetweenAppLinks);
122     if (view_in_store_link_)
123       horizontal_links_container->AddChildView(view_in_store_link_);
124     if (licenses_link_)
125       horizontal_links_container->AddChildView(licenses_link_);
126     vertical_info_container->AddChildView(horizontal_links_container);
127   }
128 }
129 void AppInfoHeaderPanel::LinkClicked(views::Link* source, int event_flags) {
130   if (source == view_in_store_link_) {
131     ShowAppInWebStore();
132   } else if (source == licenses_link_) {
133     DisplayLicenses();
134   } else {
135     NOTREACHED();
136   }
137 }
138
139 void AppInfoHeaderPanel::LoadAppImageAsync() {
140   extensions::ExtensionResource image = extensions::IconsInfo::GetIconResource(
141       app_,
142       extension_misc::EXTENSION_ICON_LARGE,
143       ExtensionIconSet::MATCH_BIGGER);
144   int pixel_size =
145       static_cast<int>(kIconSize * gfx::ImageSkia::GetMaxSupportedScale());
146   extensions::ImageLoader::Get(profile_)->LoadImageAsync(
147       app_,
148       image,
149       gfx::Size(pixel_size, pixel_size),
150       base::Bind(&AppInfoHeaderPanel::OnAppImageLoaded, AsWeakPtr()));
151 }
152
153 void AppInfoHeaderPanel::OnAppImageLoaded(const gfx::Image& image) {
154   const SkBitmap* bitmap;
155   if (image.IsEmpty()) {
156     bitmap = &extensions::util::GetDefaultAppIcon()
157                   .GetRepresentation(gfx::ImageSkia::GetMaxSupportedScale())
158                   .sk_bitmap();
159   } else {
160     bitmap = image.ToSkBitmap();
161   }
162
163   app_icon_->SetImage(gfx::ImageSkia::CreateFrom1xBitmap(*bitmap));
164 }
165
166 void AppInfoHeaderPanel::ShowAppInWebStore() const {
167   DCHECK(CanShowAppInWebStore());
168   const GURL url = extensions::ManifestURL::GetDetailsURL(app_);
169   DCHECK_NE(url, GURL::EmptyGURL());
170   chrome::NavigateParams params(
171       profile_,
172       net::AppendQueryParameter(url,
173                                 extension_urls::kWebstoreSourceField,
174                                 extension_urls::kLaunchSourceAppListInfoDialog),
175       ui::PAGE_TRANSITION_LINK);
176   chrome::Navigate(&params);
177 }
178
179 bool AppInfoHeaderPanel::CanShowAppInWebStore() const {
180   return app_->from_webstore();
181 }
182
183 void AppInfoHeaderPanel::DisplayLicenses() {
184   // Find the first shared module for this app, and display it's options page
185   // as an 'about' link.
186   // TODO(sashab): Revisit UI layout once shared module usage becomes more
187   // common.
188   DCHECK(CanDisplayLicenses());
189   ExtensionService* service =
190       extensions::ExtensionSystem::Get(profile_)->extension_service();
191   DCHECK(service);
192   const std::vector<extensions::SharedModuleInfo::ImportInfo>& imports =
193       extensions::SharedModuleInfo::GetImports(app_);
194   const extensions::Extension* imported_module =
195       service->GetExtensionById(imports[0].extension_id, true);
196   DCHECK(imported_module);
197   GURL about_page = extensions::ManifestURL::GetAboutPage(imported_module);
198   DCHECK(about_page != GURL::EmptyGURL());
199   chrome::NavigateParams params(
200       profile_, about_page, ui::PAGE_TRANSITION_LINK);
201   chrome::Navigate(&params);
202 }
203
204 bool AppInfoHeaderPanel::CanDisplayLicenses() {
205   if (!extensions::SharedModuleInfo::ImportsModules(app_))
206     return false;
207   ExtensionService* service =
208       extensions::ExtensionSystem::Get(profile_)->extension_service();
209   DCHECK(service);
210   const std::vector<extensions::SharedModuleInfo::ImportInfo>& imports =
211       extensions::SharedModuleInfo::GetImports(app_);
212   const extensions::Extension* imported_module =
213       service->GetExtensionById(imports[0].extension_id, true);
214   DCHECK(imported_module);
215   GURL about_page = extensions::ManifestURL::GetAboutPage(imported_module);
216   if (about_page == GURL::EmptyGURL())
217     return false;
218   return true;
219 }