Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(187)

Side by Side Diff: chrome/browser/ui/views/extensions/disabled_extensions_view.cc

Issue 11189094: Implement sideload wipeout for Extensions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/views/extensions/disabled_extensions_view.h"
6
7 #include "base/string_number_conversions.h"
8 #include "base/utf_string_conversions.h"
9 #include "chrome/browser/extensions/extension_service.h"
10 #include "chrome/browser/extensions/extension_system.h"
11 #include "chrome/browser/ui/browser.h"
12 #include "chrome/browser/ui/singleton_tabs.h"
13 #include "chrome/common/extensions/feature_switch.h"
14 #include "chrome/common/url_constants.h"
15 #include "content/public/browser/user_metrics.h"
16 #include "grit/generated_resources.h"
17 #include "grit/locale_settings.h"
18 #include "grit/theme_resources.h"
19 #include "ui/base/accessibility/accessible_view_state.h"
20 #include "ui/base/l10n/l10n_util.h"
21 #include "ui/base/resource/resource_bundle.h"
22 #include "ui/views/controls/button/text_button.h"
23 #include "ui/views/controls/label.h"
24 #include "ui/views/controls/image_view.h"
25 #include "ui/views/controls/link.h"
26 #include "ui/views/layout/grid_layout.h"
27 #include "ui/views/layout/layout_constants.h"
28 #include "ui/views/widget/widget.h"
29
30 using content::UserMetricsAction;
31
32 namespace {
33
34 // Layout constants.
35 const int kColumnPadding = 4;
36 const int kExtensionListPadding = 20;
37 const int kImagePadding = 7;
38 const int kInset = 2;
39 const int kHeadlineMessagePadding = 4;
40 const int kHeadlineRowPadding = 10;
41 const int kMessageBubblePadding = 11;
42
43 // How many extensions to show in the bubble (max).
44 const int kMaxExtensionsToShow = 7;
45
46 } // namespace
47
48 ////////////////////////////////////////////////////////////////////////////////
49 // DisabledExtensionsView
50
51 // static
52 bool DisabledExtensionsView::MaybeShow(Browser* browser,
53 views::View* anchor_view) {
54 #if !defined(OS_WIN)
55 // We are targeting registry-installed extensions, which is Windows-specific,
56 // and extensions marked internal and not from the web store, which are mostly
57 // problematic on Windows.
58 return false;
59 #endif
60
61 if (!extensions::FeatureSwitch::sideload_wipeout()->IsEnabled())
62 return false;
63
64 static bool done_showing_ui = false;
65 if (done_showing_ui)
66 return false; // Only show the bubble once per launch.
67
68 // Fetch all disabled extensions.
69 ExtensionService* extension_service =
70 extensions::ExtensionSystem::Get(
71 browser->profile())->extension_service();
72 scoped_ptr<const ExtensionSet> wiped_out(
73 extension_service->GenerateSideloadWipoutExtensionsSet());
74 if (wiped_out->size()) {
75 DisabledExtensionsView* bubble_delegate =
76 new DisabledExtensionsView(
77 anchor_view, browser, wiped_out.release());
78 views::BubbleDelegateView::CreateBubble(bubble_delegate);
79 bubble_delegate->StartFade(true);
80
81 done_showing_ui = true;
82 return true;
83 }
84
85 return false;
86 }
87
88 DisabledExtensionsView::DisabledExtensionsView(
89 views::View* anchor_view,
90 Browser* browser,
91 const ExtensionSet* wiped_out)
92 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT),
93 browser_(browser),
94 wiped_out_(wiped_out),
95 headline_(NULL),
96 learn_more_(NULL),
97 settings_button_(NULL),
98 dismiss_button_(NULL) {
99 set_close_on_deactivate(false);
100 set_move_with_anchor(true);
101 }
102
103 DisabledExtensionsView::~DisabledExtensionsView() {
104 }
105
106 void DisabledExtensionsView::ButtonPressed(views::Button* sender,
107 const ui::Event& event) {
108 if (sender == settings_button_) {
109 content::RecordAction(
110 UserMetricsAction("DisabledExtension_SettingsButton"));
111 browser_->OpenURL(
112 content::OpenURLParams(GURL(chrome::kChromeUIExtensionsURL),
113 content::Referrer(),
114 NEW_FOREGROUND_TAB,
115 content::PAGE_TRANSITION_LINK,
116 false));
117
118 } else if (sender == dismiss_button_) {
119 content::RecordAction(UserMetricsAction("DisabledExtension_Dismiss"));
120 // No action required. Close will happen below.
121 } else {
122 NOTREACHED();
123 }
124
125 GetWidget()->Close();
126 }
127
128 void DisabledExtensionsView::LinkClicked(
129 views::Link* source, int event_flags) {
130 content::RecordAction(UserMetricsAction("DisabledExtension_LearnMore"));
131 browser_->OpenURL(
132 content::OpenURLParams(GURL(chrome::kSideloadWipeoutHelpURL),
133 content::Referrer(),
134 NEW_FOREGROUND_TAB,
135 content::PAGE_TRANSITION_LINK,
136 false));
137
138 GetWidget()->Close();
139 }
140
141 void DisabledExtensionsView::GetAccessibleState(
142 ui::AccessibleViewState* state) {
143 state->role = ui::AccessibilityTypes::ROLE_ALERT;
144 }
145
146 void DisabledExtensionsView::ViewHierarchyChanged(
147 bool is_add, View* parent, View* child) {
148 if (is_add && child == this) {
149 GetWidget()->NotifyAccessibilityEvent(
150 this, ui::AccessibilityTypes::EVENT_ALERT, true);
151 }
152 }
153
154 void DisabledExtensionsView::Init() {
155 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
156
157 views::GridLayout* layout = views::GridLayout::CreatePanel(this);
158 layout->SetInsets(kInset, kInset, kInset, kInset);
159 SetLayoutManager(layout);
160
161 const int headline_column_set_id = 0;
162 views::ColumnSet* top_columns = layout->AddColumnSet(headline_column_set_id);
163 top_columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER,
164 0, views::GridLayout::USE_PREF, 0, 0);
165 top_columns->AddPaddingColumn(0, kImagePadding);
166 top_columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::CENTER,
167 0, views::GridLayout::USE_PREF, 0, 0);
168 top_columns->AddPaddingColumn(1, 0);
169 layout->StartRow(0, headline_column_set_id);
170
171 views::ImageView* image = new views::ImageView();
172 image->SetImage(rb.GetImageSkiaNamed(IDR_EXTENSIONS_PUZZLE_PIECE));
173 layout->AddView(image);
174
175 headline_ = new views::Label();
176 headline_->SetFont(rb.GetFont(ui::ResourceBundle::MediumFont));
177 headline_->SetText(l10n_util::GetStringUTF16(
178 IDS_OPTIONS_SIDELOAD_WIPEOUT_BUBBLE_HEADLINE));
179 layout->AddView(headline_);
180
181 layout->AddPaddingRow(0, kHeadlineRowPadding);
182
183 const int text_column_set_id = 1;
184 views::ColumnSet* upper_columns = layout->AddColumnSet(text_column_set_id);
185 upper_columns->AddPaddingColumn(0, kColumnPadding);
186 upper_columns->AddColumn(
187 views::GridLayout::LEADING, views::GridLayout::LEADING,
188 0, views::GridLayout::USE_PREF, 0, 0);
189 layout->StartRow(0, text_column_set_id);
190
191 views::Label* message = new views::Label();
192 message->SetMultiLine(true);
193 message->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
194 message->SetText(
195 l10n_util::GetStringUTF16(IDS_OPTIONS_SIDELOAD_WIPEOUT_WHAT_HAPPENED));
196 message->SizeToFit(views::Widget::GetLocalizedContentsWidth(
197 IDS_DISABLED_EXTENSIONS_BUBBLE_WIDTH_CHARS));
198 layout->AddView(message);
199
200 const int extension_list_column_set_id = 2;
201 views::ColumnSet* middle_columns =
202 layout->AddColumnSet(extension_list_column_set_id);
203 middle_columns->AddPaddingColumn(0, kExtensionListPadding);
204 middle_columns->AddColumn(
205 views::GridLayout::LEADING, views::GridLayout::CENTER,
206 0, views::GridLayout::USE_PREF, 0, 0);
207
208 layout->StartRowWithPadding(0, extension_list_column_set_id,
209 0, kHeadlineMessagePadding);
210 views::Label* extensions = new views::Label();
211 extensions->SetMultiLine(true);
212 extensions->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
213 extensions->SetFont(extensions->font().DeriveFont(0, gfx::Font::ITALIC));
214
215 std::vector<string16> extension_list;
216 int count = 0;
217 for (ExtensionSet::const_iterator iter = wiped_out_->begin();
218 iter != wiped_out_->end() && count < kMaxExtensionsToShow; ++iter) {
219 const extensions::Extension* extension = *iter;
220 extension_list.push_back(ASCIIToUTF16("- ") +
221 UTF8ToUTF16(extension->name()));
222 count++;
223 }
224
225 if (count == kMaxExtensionsToShow) {
226 string16 difference =
227 base::IntToString16(wiped_out_->size() - kMaxExtensionsToShow);
228 extension_list.push_back(ASCIIToUTF16("- ") +
229 l10n_util::GetStringFUTF16(IDS_OPTIONS_SIDELOAD_WIPEOUT_OVERFLOW,
230 difference));
231 }
232
233 extensions->SetText(JoinString(extension_list, ASCIIToUTF16("\n")));
234 extensions->SizeToFit(views::Widget::GetLocalizedContentsWidth(
235 IDS_DISABLED_EXTENSIONS_BUBBLE_WIDTH_CHARS));
236 layout->AddView(extensions);
237
238 layout->StartRowWithPadding(
239 0, text_column_set_id, 0, kHeadlineMessagePadding);
240 views::Label* recourse = new views::Label();
241 recourse->SetMultiLine(true);
242 recourse->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
243 recourse->SetText(
244 l10n_util::GetStringUTF16(IDS_OPTIONS_SIDELOAD_WIPEOUT_RECOURSE));
245 recourse->SizeToFit(views::Widget::GetLocalizedContentsWidth(
246 IDS_DISABLED_EXTENSIONS_BUBBLE_WIDTH_CHARS));
247 layout->AddView(recourse);
248
249 const int action_row_column_set_id = 3;
250 views::ColumnSet* bottom_columns =
251 layout->AddColumnSet(action_row_column_set_id);
252 bottom_columns->AddPaddingColumn(0, kColumnPadding);
253 bottom_columns->AddColumn(views::GridLayout::LEADING,
254 views::GridLayout::TRAILING, 0, views::GridLayout::USE_PREF, 0, 0);
255 bottom_columns->AddPaddingColumn(1, views::kRelatedButtonHSpacing);
256 bottom_columns->AddColumn(views::GridLayout::TRAILING,
257 views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0);
258 bottom_columns->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
259 bottom_columns->AddColumn(views::GridLayout::TRAILING,
260 views::GridLayout::CENTER, 0, views::GridLayout::USE_PREF, 0, 0);
261 layout->StartRowWithPadding(0, action_row_column_set_id,
262 0, kMessageBubblePadding);
263
264 learn_more_ = new views::Link(l10n_util::GetStringUTF16(IDS_LEARN_MORE));
265 learn_more_->set_listener(this);
266 layout->AddView(learn_more_);
267
268 settings_button_ = new views::NativeTextButton(this,
269 l10n_util::GetStringUTF16(IDS_OPTIONS_SIDELOAD_WIPEOUT_SETTINGS));
270 settings_button_->SetIsDefault(true);
271 layout->AddView(settings_button_);
272 dismiss_button_ = new views::NativeTextButton(this,
273 l10n_util::GetStringUTF16(IDS_OPTIONS_SIDELOAD_WIPEOUT_DISMISS));
274 dismiss_button_->SetFont(
275 dismiss_button_->font().DeriveFont(0, gfx::Font::BOLD));
276 layout->AddView(dismiss_button_);
277
278 content::RecordAction(
279 UserMetricsAction("DisabledExtensionNotificationShown"));
280 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698