Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / extensions / extension_message_bubble_controller.cc
blob278ad8ddaa287421a88c5a5e747e493a44138617
1 // Copyright (c) 2013 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.
5 #include "chrome/browser/extensions/extension_message_bubble_controller.h"
7 #include "base/bind.h"
8 #include "base/metrics/histogram.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/extensions/extension_message_bubble.h"
13 #include "chrome/browser/extensions/extension_toolbar_model.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/browser_finder.h"
17 #include "chrome/common/url_constants.h"
18 #include "content/public/browser/user_metrics.h"
19 #include "extensions/browser/extension_prefs.h"
20 #include "extensions/browser/extension_registry.h"
21 #include "grit/components_strings.h"
22 #include "ui/base/l10n/l10n_util.h"
24 namespace extensions {
26 namespace {
27 // How many extensions to show in the bubble (max).
28 const int kMaxExtensionsToShow = 7;
31 ////////////////////////////////////////////////////////////////////////////////
32 // ExtensionMessageBubbleController::Delegate
34 ExtensionMessageBubbleController::Delegate::Delegate(Profile* profile)
35 : profile_(profile) {
38 ExtensionMessageBubbleController::Delegate::~Delegate() {
41 void ExtensionMessageBubbleController::Delegate::RestrictToSingleExtension(
42 const std::string& extension_id) {
43 NOTIMPLEMENTED(); // Derived classes that need this should implement.
46 base::string16 ExtensionMessageBubbleController::Delegate::GetLearnMoreLabel()
47 const {
48 return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
51 bool ExtensionMessageBubbleController::Delegate::HasBubbleInfoBeenAcknowledged(
52 const std::string& extension_id) {
53 std::string pref_name = get_acknowledged_flag_pref_name();
54 if (pref_name.empty())
55 return false;
56 bool pref_state = false;
57 extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(profile_);
58 prefs->ReadPrefAsBoolean(extension_id, pref_name, &pref_state);
59 return pref_state;
62 void ExtensionMessageBubbleController::Delegate::SetBubbleInfoBeenAcknowledged(
63 const std::string& extension_id,
64 bool value) {
65 std::string pref_name = get_acknowledged_flag_pref_name();
66 if (pref_name.empty())
67 return;
68 extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(profile_);
69 prefs->UpdateExtensionPref(extension_id,
70 pref_name,
71 value ? new base::FundamentalValue(value) : NULL);
74 Profile* ExtensionMessageBubbleController::Delegate::profile() const {
75 return profile_;
78 std::string
79 ExtensionMessageBubbleController::Delegate::get_acknowledged_flag_pref_name()
80 const {
81 return acknowledged_pref_name_;
84 void
85 ExtensionMessageBubbleController::Delegate::set_acknowledged_flag_pref_name(
86 std::string pref_name) {
87 acknowledged_pref_name_ = pref_name;
90 ////////////////////////////////////////////////////////////////////////////////
91 // ExtensionMessageBubbleController
93 ExtensionMessageBubbleController::ExtensionMessageBubbleController(
94 Delegate* delegate, Profile* profile)
95 : profile_(profile),
96 user_action_(ACTION_BOUNDARY),
97 delegate_(delegate),
98 initialized_(false),
99 did_highlight_(false) {
102 ExtensionMessageBubbleController::~ExtensionMessageBubbleController() {
105 std::vector<base::string16>
106 ExtensionMessageBubbleController::GetExtensionList() {
107 ExtensionIdList* list = GetOrCreateExtensionList();
108 if (list->empty())
109 return std::vector<base::string16>();
111 ExtensionRegistry* registry = ExtensionRegistry::Get(profile_);
112 std::vector<base::string16> return_value;
113 for (ExtensionIdList::const_iterator it = list->begin();
114 it != list->end(); ++it) {
115 const Extension* extension =
116 registry->GetExtensionById(*it, ExtensionRegistry::EVERYTHING);
117 if (extension) {
118 return_value.push_back(base::UTF8ToUTF16(extension->name()));
119 } else {
120 return_value.push_back(
121 base::ASCIIToUTF16(std::string("(unknown name) ") + *it));
122 // TODO(finnur): Add this as a string to the grd, for next milestone.
125 return return_value;
128 base::string16 ExtensionMessageBubbleController::GetExtensionListForDisplay() {
129 if (!delegate_->ShouldShowExtensionList())
130 return base::string16();
132 std::vector<base::string16> extension_list = GetExtensionList();
133 if (extension_list.size() > kMaxExtensionsToShow) {
134 int old_size = extension_list.size();
135 extension_list.erase(extension_list.begin() + kMaxExtensionsToShow,
136 extension_list.end());
137 extension_list.push_back(delegate_->GetOverflowText(base::IntToString16(
138 old_size - kMaxExtensionsToShow)));
140 const base::char16 bullet_point = 0x2022;
141 base::string16 prefix = bullet_point + base::ASCIIToUTF16(" ");
142 for (base::string16& str : extension_list)
143 str.insert(0, prefix);
144 return base::JoinString(extension_list, base::ASCIIToUTF16("\n"));
147 const ExtensionIdList& ExtensionMessageBubbleController::GetExtensionIdList() {
148 return *GetOrCreateExtensionList();
151 bool ExtensionMessageBubbleController::CloseOnDeactivate() { return false; }
153 void ExtensionMessageBubbleController::HighlightExtensionsIfNecessary() {
154 if (delegate_->ShouldHighlightExtensions() && !did_highlight_) {
155 did_highlight_ = true;
156 const ExtensionIdList& extension_ids = GetExtensionIdList();
157 DCHECK(!extension_ids.empty());
158 ExtensionToolbarModel::Get(profile_)->HighlightExtensions(
159 extension_ids, ExtensionToolbarModel::HIGHLIGHT_WARNING);
163 void ExtensionMessageBubbleController::Show(ExtensionMessageBubble* bubble) {
164 bubble->Show();
167 void ExtensionMessageBubbleController::OnBubbleAction() {
168 DCHECK_EQ(ACTION_BOUNDARY, user_action_);
169 user_action_ = ACTION_EXECUTE;
171 delegate_->LogAction(ACTION_EXECUTE);
172 delegate_->PerformAction(*GetOrCreateExtensionList());
174 OnClose();
177 void ExtensionMessageBubbleController::OnBubbleDismiss() {
178 // OnBubbleDismiss() can be called twice when we receive multiple
179 // "OnWidgetDestroying" notifications (this can at least happen when we close
180 // a window with a notification open). Handle this gracefully.
181 if (user_action_ != ACTION_BOUNDARY) {
182 DCHECK(user_action_ == ACTION_DISMISS);
183 return;
186 user_action_ = ACTION_DISMISS;
188 delegate_->LogAction(ACTION_DISMISS);
190 OnClose();
193 void ExtensionMessageBubbleController::OnLinkClicked() {
194 DCHECK_EQ(ACTION_BOUNDARY, user_action_);
195 user_action_ = ACTION_LEARN_MORE;
197 delegate_->LogAction(ACTION_LEARN_MORE);
198 Browser* browser =
199 chrome::FindBrowserWithProfile(profile_, chrome::GetActiveDesktop());
200 if (browser) {
201 browser->OpenURL(
202 content::OpenURLParams(delegate_->GetLearnMoreUrl(),
203 content::Referrer(),
204 NEW_FOREGROUND_TAB,
205 ui::PAGE_TRANSITION_LINK,
206 false));
208 OnClose();
211 void ExtensionMessageBubbleController::AcknowledgeExtensions() {
212 ExtensionIdList* list = GetOrCreateExtensionList();
213 for (ExtensionIdList::const_iterator it = list->begin();
214 it != list->end(); ++it)
215 delegate_->AcknowledgeExtension(*it, user_action_);
218 ExtensionIdList* ExtensionMessageBubbleController::GetOrCreateExtensionList() {
219 if (!initialized_) {
220 scoped_ptr<const ExtensionSet> extension_set(
221 ExtensionRegistry::Get(profile_)->GenerateInstalledExtensionsSet());
222 for (ExtensionSet::const_iterator it = extension_set->begin();
223 it != extension_set->end(); ++it) {
224 std::string id = (*it)->id();
225 if (!delegate_->ShouldIncludeExtension(id))
226 continue;
227 extension_list_.push_back(id);
230 delegate_->LogExtensionCount(extension_list_.size());
231 initialized_ = true;
234 return &extension_list_;
237 void ExtensionMessageBubbleController::OnClose() {
238 AcknowledgeExtensions();
239 if (did_highlight_)
240 ExtensionToolbarModel::Get(profile_)->StopHighlighting();
243 } // namespace extensions