Upstream version 11.39.264.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / apps / app_info_dialog / app_info_permissions_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_permissions_panel.h"
6
7 #include <string>
8 #include <vector>
9
10 #include "apps/app_load_service.h"
11 #include "apps/saved_files_service.h"
12 #include "base/files/file_path.h"
13 #include "chrome/grit/generated_resources.h"
14 #include "extensions/common/extension.h"
15 #include "extensions/common/permissions/api_permission.h"
16 #include "extensions/common/permissions/permissions_data.h"
17 #include "ui/base/l10n/l10n_util.h"
18 #include "ui/views/controls/button/label_button.h"
19 #include "ui/views/controls/label.h"
20 #include "ui/views/layout/box_layout.h"
21 #include "ui/views/layout/grid_layout.h"
22 #include "ui/views/layout/layout_constants.h"
23 #include "ui/views/view.h"
24 #include "ui/views/widget/widget.h"
25
26 AppInfoPermissionsPanel::AppInfoPermissionsPanel(
27     Profile* profile,
28     const extensions::Extension* app)
29     : AppInfoPanel(profile, app),
30       active_permissions_heading_(NULL),
31       active_permissions_list_(NULL),
32       retained_files_heading_(NULL),
33       retained_files_list_(NULL),
34       revoke_file_permissions_button_(NULL) {
35   // Create UI elements.
36   CreateActivePermissionsControl();
37   CreateRetainedFilesControl();
38
39   // Layout elements.
40   SetLayoutManager(
41       new views::BoxLayout(views::BoxLayout::kVertical,
42                            0,
43                            0,
44                            views::kUnrelatedControlVerticalSpacing));
45
46   LayoutActivePermissionsControl();
47   LayoutRetainedFilesControl();
48 }
49
50 AppInfoPermissionsPanel::~AppInfoPermissionsPanel() {
51   // Destroy view children before their models.
52   RemoveAllChildViews(true);
53 }
54
55 // Given a list of strings, returns a view containing a list of these strings
56 // as bulleted items.
57 views::View* AppInfoPermissionsPanel::CreateBulletedListView(
58     const std::vector<base::string16>& messages,
59     bool allow_multiline,
60     gfx::ElideBehavior elide_behavior) {
61   const int kSpacingBetweenBulletAndStartOfText = 5;
62
63   views::View* list_view = new views::View();
64   views::GridLayout* layout = new views::GridLayout(list_view);
65   list_view->SetLayoutManager(layout);
66
67   // Create 2 columns: one for the bullet, one for the bullet text.
68   static const int kColumnSetId = 1;
69   views::ColumnSet* column_set = layout->AddColumnSet(kColumnSetId);
70   column_set->AddColumn(views::GridLayout::FILL,
71                         views::GridLayout::LEADING,
72                         0,
73                         views::GridLayout::USE_PREF,
74                         0,
75                         0);
76   column_set->AddPaddingColumn(0, kSpacingBetweenBulletAndStartOfText);
77   column_set->AddColumn(views::GridLayout::FILL,
78                         views::GridLayout::LEADING,
79                         1,
80                         views::GridLayout::USE_PREF,
81                         0,
82                         0);
83
84   for (std::vector<base::string16>::const_iterator it = messages.begin();
85        it != messages.end();
86        ++it) {
87     views::Label* permission_label = new views::Label(*it);
88     permission_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
89
90     if (allow_multiline)
91       permission_label->SetMultiLine(true);
92     else
93       permission_label->SetElideBehavior(elide_behavior);
94
95     // Extract only the bullet from the IDS_EXTENSION_PERMISSION_LINE text.
96     views::Label* bullet_label = new views::Label(l10n_util::GetStringFUTF16(
97         IDS_EXTENSION_PERMISSION_LINE, base::string16()));
98
99     // Add a padding row before every item except the first
100     if (it != messages.begin())
101       layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
102
103     layout->StartRow(1, kColumnSetId);
104     layout->AddView(bullet_label);
105     layout->AddView(permission_label);
106   }
107
108   return list_view;
109 }
110
111 void AppInfoPermissionsPanel::CreateActivePermissionsControl() {
112   std::vector<base::string16> permission_strings =
113       GetActivePermissionMessages();
114   if (permission_strings.empty()) {
115     views::Label* no_permissions_text = new views::Label(
116         l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_NO_PERMISSIONS_TEXT));
117     no_permissions_text->SetHorizontalAlignment(gfx::ALIGN_LEFT);
118     active_permissions_list_ = no_permissions_text;
119   } else {
120     active_permissions_heading_ = CreateHeading(l10n_util::GetStringUTF16(
121         IDS_APPLICATION_INFO_ACTIVE_PERMISSIONS_TEXT));
122     active_permissions_list_ =
123         CreateBulletedListView(permission_strings, true, gfx::NO_ELIDE);
124   }
125 }
126
127 void AppInfoPermissionsPanel::CreateRetainedFilesControl() {
128   const std::vector<base::string16> retained_file_permission_messages =
129       GetRetainedFilePaths();
130
131   if (!retained_file_permission_messages.empty()) {
132     revoke_file_permissions_button_ = new views::LabelButton(
133         this,
134         l10n_util::GetStringUTF16(
135             IDS_APPLICATION_INFO_REVOKE_RETAINED_FILE_PERMISSIONS_BUTTON_TEXT));
136     revoke_file_permissions_button_->SetStyle(views::Button::STYLE_BUTTON);
137
138     retained_files_heading_ = CreateHeading(l10n_util::GetStringUTF16(
139         IDS_APPLICATION_INFO_RETAINED_FILE_PERMISSIONS_TEXT));
140     retained_files_list_ = CreateBulletedListView(
141         retained_file_permission_messages, false, gfx::ELIDE_MIDDLE);
142   }
143 }
144
145 void AppInfoPermissionsPanel::LayoutActivePermissionsControl() {
146   if (active_permissions_list_) {
147     views::View* vertical_stack = CreateVerticalStack();
148     if (active_permissions_heading_)
149       vertical_stack->AddChildView(active_permissions_heading_);
150     vertical_stack->AddChildView(active_permissions_list_);
151
152     AddChildView(vertical_stack);
153   }
154 }
155
156 void AppInfoPermissionsPanel::LayoutRetainedFilesControl() {
157   if (retained_files_list_) {
158     DCHECK(retained_files_heading_);
159     DCHECK(revoke_file_permissions_button_);
160
161     // Add a sub-view so the revoke button is right-aligned.
162     views::View* right_aligned_button = new views::View();
163     views::BoxLayout* right_aligned_horizontal_layout =
164         new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0);
165     right_aligned_horizontal_layout->set_main_axis_alignment(
166         views::BoxLayout::MAIN_AXIS_ALIGNMENT_END);
167     right_aligned_button->SetLayoutManager(right_aligned_horizontal_layout);
168     right_aligned_button->AddChildView(revoke_file_permissions_button_);
169
170     views::View* vertical_stack = CreateVerticalStack();
171     vertical_stack->AddChildView(retained_files_heading_);
172     vertical_stack->AddChildView(retained_files_list_);
173     vertical_stack->AddChildView(right_aligned_button);
174
175     AddChildView(vertical_stack);
176   }
177 }
178
179 void AppInfoPermissionsPanel::ButtonPressed(views::Button* sender,
180                                             const ui::Event& event) {
181   if (sender == revoke_file_permissions_button_) {
182     RevokeFilePermissions();
183   } else {
184     NOTREACHED();
185   }
186 }
187
188 const std::vector<base::string16>
189 AppInfoPermissionsPanel::GetActivePermissionMessages() const {
190   return app_->permissions_data()->GetPermissionMessageStrings();
191 }
192
193 const std::vector<base::string16>
194 AppInfoPermissionsPanel::GetRetainedFilePaths() const {
195   std::vector<base::string16> retained_file_paths;
196   if (app_->permissions_data()->HasAPIPermission(
197           extensions::APIPermission::kFileSystem)) {
198     std::vector<apps::SavedFileEntry> retained_file_entries =
199         apps::SavedFilesService::Get(profile_)->GetAllFileEntries(app_->id());
200     for (std::vector<apps::SavedFileEntry>::const_iterator it =
201              retained_file_entries.begin();
202          it != retained_file_entries.end();
203          ++it) {
204       retained_file_paths.push_back(it->path.LossyDisplayName());
205     }
206   }
207   return retained_file_paths;
208 }
209
210 void AppInfoPermissionsPanel::RevokeFilePermissions() {
211   apps::SavedFilesService::Get(profile_)->ClearQueue(app_);
212   apps::AppLoadService::Get(profile_)->RestartApplicationIfRunning(app_->id());
213
214   GetWidget()->Close();
215 }