5d9bc990fdf08b5e99f0d96dc6776e82596158fe
[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   if (!view_in_store_link_ && !licenses_link_) {
104     // If there's no links, allow the app's name to take up multiple lines.
105     // TODO(sashab): Limit the number of lines to 2.
106     app_name_label_->SetMultiLine(true);
107     AddChildView(app_name_label_);
108   } else {
109     // Create a vertical container to store the app's name and links.
110     views::View* vertical_info_container = new views::View();
111     views::BoxLayout* vertical_container_layout =
112         new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0);
113     vertical_container_layout->set_main_axis_alignment(
114         views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
115     vertical_info_container->SetLayoutManager(vertical_container_layout);
116
117     vertical_info_container->AddChildView(app_name_label_);
118     // Create a horizontal container to store the app's links.
119     views::View* horizontal_links_container =
120         CreateHorizontalStack(kSpacingBetweenAppLinks);
121     if (view_in_store_link_)
122       horizontal_links_container->AddChildView(view_in_store_link_);
123     if (licenses_link_)
124       horizontal_links_container->AddChildView(licenses_link_);
125     vertical_info_container->AddChildView(horizontal_links_container);
126
127     AddChildView(vertical_info_container);
128   }
129 }
130 void AppInfoHeaderPanel::LinkClicked(views::Link* source, int event_flags) {
131   if (source == view_in_store_link_) {
132     ShowAppInWebStore();
133   } else if (source == licenses_link_) {
134     DisplayLicenses();
135   } else {
136     NOTREACHED();
137   }
138 }
139
140 void AppInfoHeaderPanel::LoadAppImageAsync() {
141   extensions::ExtensionResource image = extensions::IconsInfo::GetIconResource(
142       app_,
143       extension_misc::EXTENSION_ICON_LARGE,
144       ExtensionIconSet::MATCH_BIGGER);
145   int pixel_size =
146       static_cast<int>(kIconSize * gfx::ImageSkia::GetMaxSupportedScale());
147   extensions::ImageLoader::Get(profile_)->LoadImageAsync(
148       app_,
149       image,
150       gfx::Size(pixel_size, pixel_size),
151       base::Bind(&AppInfoHeaderPanel::OnAppImageLoaded, AsWeakPtr()));
152 }
153
154 void AppInfoHeaderPanel::OnAppImageLoaded(const gfx::Image& image) {
155   const SkBitmap* bitmap;
156   if (image.IsEmpty()) {
157     bitmap = &extensions::util::GetDefaultAppIcon()
158                   .GetRepresentation(gfx::ImageSkia::GetMaxSupportedScale())
159                   .sk_bitmap();
160   } else {
161     bitmap = image.ToSkBitmap();
162   }
163
164   app_icon_->SetImage(gfx::ImageSkia::CreateFrom1xBitmap(*bitmap));
165 }
166
167 void AppInfoHeaderPanel::ShowAppInWebStore() const {
168   DCHECK(CanShowAppInWebStore());
169   const GURL url = extensions::ManifestURL::GetDetailsURL(app_);
170   DCHECK_NE(url, GURL::EmptyGURL());
171   chrome::NavigateParams params(
172       profile_,
173       net::AppendQueryParameter(url,
174                                 extension_urls::kWebstoreSourceField,
175                                 extension_urls::kLaunchSourceAppListInfoDialog),
176       content::PAGE_TRANSITION_LINK);
177   chrome::Navigate(&params);
178 }
179
180 bool AppInfoHeaderPanel::CanShowAppInWebStore() const {
181   return app_->from_webstore();
182 }
183
184 void AppInfoHeaderPanel::DisplayLicenses() {
185   // Find the first shared module for this app, and display it's options page
186   // as an 'about' link.
187   // TODO(sashab): Revisit UI layout once shared module usage becomes more
188   // common.
189   DCHECK(CanDisplayLicenses());
190   ExtensionService* service =
191       extensions::ExtensionSystem::Get(profile_)->extension_service();
192   DCHECK(service);
193   const std::vector<extensions::SharedModuleInfo::ImportInfo>& imports =
194       extensions::SharedModuleInfo::GetImports(app_);
195   const extensions::Extension* imported_module =
196       service->GetExtensionById(imports[0].extension_id, true);
197   DCHECK(imported_module);
198   GURL about_page = extensions::ManifestURL::GetAboutPage(imported_module);
199   DCHECK(about_page != GURL::EmptyGURL());
200   chrome::NavigateParams params(
201       profile_, about_page, content::PAGE_TRANSITION_LINK);
202   chrome::Navigate(&params);
203 }
204
205 bool AppInfoHeaderPanel::CanDisplayLicenses() {
206   if (!extensions::SharedModuleInfo::ImportsModules(app_))
207     return false;
208   ExtensionService* service =
209       extensions::ExtensionSystem::Get(profile_)->extension_service();
210   DCHECK(service);
211   const std::vector<extensions::SharedModuleInfo::ImportInfo>& imports =
212       extensions::SharedModuleInfo::GetImports(app_);
213   const extensions::Extension* imported_module =
214       service->GetExtensionById(imports[0].extension_id, true);
215   DCHECK(imported_module);
216   GURL about_page = extensions::ManifestURL::GetAboutPage(imported_module);
217   if (about_page == GURL::EmptyGURL())
218     return false;
219   return true;
220 }