Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / apps / app_info_dialog / app_info_dialog_views.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_dialog_views.h"
6
7 #include "base/bind.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/metrics/histogram.h"
10 #include "chrome/browser/chrome_notification_types.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
13 #include "chrome/browser/ui/views/app_list/app_list_dialog_container.h"
14 #include "chrome/browser/ui/views/apps/app_info_dialog/app_info_footer_panel.h"
15 #include "chrome/browser/ui/views/apps/app_info_dialog/app_info_header_panel.h"
16 #include "chrome/browser/ui/views/apps/app_info_dialog/app_info_permissions_panel.h"
17 #include "chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.h"
18 #include "components/constrained_window/constrained_window_views.h"
19 #include "extensions/browser/extension_registry.h"
20 #include "extensions/common/extension.h"
21 #include "extensions/common/manifest.h"
22 #include "ui/app_list/app_list_constants.h"
23 #include "ui/gfx/geometry/rect.h"
24 #include "ui/gfx/geometry/size.h"
25 #include "ui/views/border.h"
26 #include "ui/views/controls/scroll_view.h"
27 #include "ui/views/layout/box_layout.h"
28 #include "ui/views/layout/layout_constants.h"
29 #include "ui/views/widget/widget.h"
30 #include "ui/views/window/dialog_delegate.h"
31
32 void ShowAppInfoInAppList(gfx::NativeWindow parent,
33                           const gfx::Rect& app_list_bounds,
34                           Profile* profile,
35                           const extensions::Extension* app,
36                           const base::Closure& close_callback) {
37   UMA_HISTOGRAM_ENUMERATION("Apps.AppInfoDialogOpenedForType",
38                             app->GetType(),
39                             extensions::Manifest::NUM_LOAD_TYPES);
40   UMA_HISTOGRAM_ENUMERATION("Apps.AppInfoDialogOpenedForLocation",
41                             app->location(),
42                             extensions::Manifest::NUM_LOCATIONS);
43
44   views::View* app_info_view = new AppInfoDialog(parent, profile, app);
45   views::DialogDelegate* dialog =
46       CreateAppListContainerForView(app_info_view, close_callback);
47   views::Widget* dialog_widget = CreateBrowserModalDialogViews(dialog, parent);
48   dialog_widget->SetBounds(app_list_bounds);
49   dialog_widget->Show();
50 }
51
52 void ShowAppInfoInNativeDialog(gfx::NativeWindow parent,
53                                const gfx::Size& size,
54                                Profile* profile,
55                                const extensions::Extension* app,
56                                const base::Closure& close_callback) {
57   views::View* app_info_view = new AppInfoDialog(parent, profile, app);
58   views::DialogDelegate* dialog =
59       CreateDialogContainerForView(app_info_view, size, close_callback);
60   views::Widget* dialog_widget = CreateBrowserModalDialogViews(dialog, parent);
61   dialog_widget->Show();
62 }
63
64 AppInfoDialog::AppInfoDialog(gfx::NativeWindow parent_window,
65                              Profile* profile,
66                              const extensions::Extension* app)
67     : dialog_header_(NULL),
68       dialog_body_(NULL),
69       dialog_footer_(NULL),
70       profile_(profile),
71       app_id_(app->id()),
72       extension_registry_(NULL) {
73   UMA_HISTOGRAM_ENUMERATION("Apps.AppInfoDialogOpenedForType",
74                             app->GetType(),
75                             extensions::Manifest::NUM_LOAD_TYPES);
76   UMA_HISTOGRAM_ENUMERATION("Apps.AppInfoDialogOpenedForLocation",
77                             app->location(),
78                             extensions::Manifest::NUM_LOCATIONS);
79
80   views::BoxLayout* layout =
81       new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0);
82   SetLayoutManager(layout);
83
84   const int kHorizontalSeparatorHeight = 1;
85   dialog_header_ = new AppInfoHeaderPanel(profile, app);
86   dialog_header_->SetBorder(views::Border::CreateSolidSidedBorder(
87       0, 0, kHorizontalSeparatorHeight, 0, app_list::kDialogSeparatorColor));
88
89   dialog_footer_ = new AppInfoFooterPanel(parent_window, profile, app);
90   dialog_footer_->SetBorder(views::Border::CreateSolidSidedBorder(
91       kHorizontalSeparatorHeight, 0, 0, 0, app_list::kDialogSeparatorColor));
92   if (!dialog_footer_->has_children()) {
93     // If there are no controls in the footer, don't add it to the dialog.
94     delete dialog_footer_;
95     dialog_footer_ = NULL;
96   }
97
98   // Make a vertically stacked view of all the panels we want to display in the
99   // dialog.
100   views::View* dialog_body_contents = new views::View();
101   dialog_body_contents->SetLayoutManager(
102       new views::BoxLayout(views::BoxLayout::kVertical,
103                            views::kButtonHEdgeMarginNew,
104                            views::kPanelVertMargin,
105                            views::kUnrelatedControlVerticalSpacing));
106   dialog_body_contents->AddChildView(new AppInfoSummaryPanel(profile, app));
107   dialog_body_contents->AddChildView(new AppInfoPermissionsPanel(profile, app));
108
109   // Clip the scrollable view so that the scrollbar appears. As long as this
110   // is larger than the height of the dialog, it will be resized to the dialog's
111   // actual height.
112   // TODO(sashab): Add ClipHeight() as a parameter-less method to
113   // views::ScrollView() to mimic this behaviour.
114   const int kMaxDialogHeight = 1000;
115   dialog_body_ = new views::ScrollView();
116   dialog_body_->ClipHeightTo(kMaxDialogHeight, kMaxDialogHeight);
117   dialog_body_->SetContents(dialog_body_contents);
118
119   AddChildView(dialog_header_);
120
121   AddChildView(dialog_body_);
122   layout->SetFlexForView(dialog_body_, 1);
123
124   if (dialog_footer_)
125     AddChildView(dialog_footer_);
126
127   // Close the dialog if the app is uninstalled, or if the profile is destroyed.
128   StartObservingExtensionRegistry();
129 }
130
131 AppInfoDialog::~AppInfoDialog() {
132   StopObservingExtensionRegistry();
133 }
134
135 void AppInfoDialog::Close() {
136   GetWidget()->Close();
137 }
138
139 void AppInfoDialog::StartObservingExtensionRegistry() {
140   DCHECK(!extension_registry_);
141
142   extension_registry_ = extensions::ExtensionRegistry::Get(profile_);
143   extension_registry_->AddObserver(this);
144 }
145
146 void AppInfoDialog::StopObservingExtensionRegistry() {
147   if (extension_registry_)
148     extension_registry_->RemoveObserver(this);
149   extension_registry_ = NULL;
150 }
151
152 void AppInfoDialog::OnExtensionUninstalled(
153     content::BrowserContext* browser_context,
154     const extensions::Extension* extension,
155     extensions::UninstallReason reason) {
156   if (extension->id() != app_id_)
157     return;
158
159   Close();
160 }
161
162 void AppInfoDialog::OnShutdown(extensions::ExtensionRegistry* registry) {
163   DCHECK_EQ(extension_registry_, registry);
164   StopObservingExtensionRegistry();
165   Close();
166 }