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"
8 #include "base/metrics/histogram.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/extensions/extension_message_bubble.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/browser_finder.h"
14 #include "chrome/common/url_constants.h"
15 #include "content/public/browser/user_metrics.h"
16 #include "extensions/browser/extension_registry.h"
17 #include "grit/chromium_strings.h"
18 #include "grit/generated_resources.h"
19 #include "ui/base/l10n/l10n_util.h"
21 namespace extensions {
23 ////////////////////////////////////////////////////////////////////////////////
24 // ExtensionMessageBubbleController::Delegate
26 ExtensionMessageBubbleController::Delegate::Delegate() {
29 ExtensionMessageBubbleController::Delegate::~Delegate() {
32 void ExtensionMessageBubbleController::Delegate::RestrictToSingleExtension(
33 const std::string& extension_id) {
34 NOTIMPLEMENTED(); // Derived classes that need this should implement.
37 ////////////////////////////////////////////////////////////////////////////////
38 // ExtensionMessageBubbleController
40 ExtensionMessageBubbleController::ExtensionMessageBubbleController(
41 Delegate* delegate, Profile* profile)
43 user_action_(ACTION_BOUNDARY),
48 ExtensionMessageBubbleController::~ExtensionMessageBubbleController() {
51 std::vector<base::string16>
52 ExtensionMessageBubbleController::GetExtensionList() {
53 ExtensionIdList* list = GetOrCreateExtensionList();
55 return std::vector<base::string16>();
57 ExtensionRegistry* registry = ExtensionRegistry::Get(profile_);
58 std::vector<base::string16> return_value;
59 for (ExtensionIdList::const_iterator it = list->begin();
60 it != list->end(); ++it) {
61 const Extension* extension =
62 registry->GetExtensionById(*it, ExtensionRegistry::EVERYTHING);
64 return_value.push_back(base::UTF8ToUTF16(extension->name()));
66 return_value.push_back(
67 base::ASCIIToUTF16(std::string("(unknown name) ") + *it));
68 // TODO(finnur): Add this as a string to the grd, for next milestone.
74 const ExtensionIdList& ExtensionMessageBubbleController::GetExtensionIdList() {
75 return *GetOrCreateExtensionList();
78 bool ExtensionMessageBubbleController::CloseOnDeactivate() { return false; }
80 void ExtensionMessageBubbleController::Show(ExtensionMessageBubble* bubble) {
81 // Wire up all the callbacks, to get notified what actions the user took.
82 base::Closure dismiss_button_callback =
83 base::Bind(&ExtensionMessageBubbleController::OnBubbleDismiss,
84 base::Unretained(this));
85 base::Closure action_button_callback =
86 base::Bind(&ExtensionMessageBubbleController::OnBubbleAction,
87 base::Unretained(this));
88 base::Closure link_callback =
89 base::Bind(&ExtensionMessageBubbleController::OnLinkClicked,
90 base::Unretained(this));
91 bubble->OnActionButtonClicked(action_button_callback);
92 bubble->OnDismissButtonClicked(dismiss_button_callback);
93 bubble->OnLinkClicked(link_callback);
98 void ExtensionMessageBubbleController::OnBubbleAction() {
99 DCHECK_EQ(ACTION_BOUNDARY, user_action_);
100 user_action_ = ACTION_EXECUTE;
102 delegate_->LogAction(ACTION_EXECUTE);
103 delegate_->PerformAction(*GetOrCreateExtensionList());
104 AcknowledgeExtensions();
105 delegate_->OnClose();
108 void ExtensionMessageBubbleController::OnBubbleDismiss() {
109 // OnBubbleDismiss() can be called twice when we receive multiple
110 // "OnWidgetDestroying" notifications (this can at least happen when we close
111 // a window with a notification open). Handle this gracefully.
112 if (user_action_ != ACTION_BOUNDARY) {
113 DCHECK(user_action_ == ACTION_DISMISS);
117 user_action_ = ACTION_DISMISS;
119 delegate_->LogAction(ACTION_DISMISS);
120 AcknowledgeExtensions();
121 delegate_->OnClose();
124 void ExtensionMessageBubbleController::OnLinkClicked() {
125 DCHECK_EQ(ACTION_BOUNDARY, user_action_);
126 user_action_ = ACTION_LEARN_MORE;
128 delegate_->LogAction(ACTION_LEARN_MORE);
130 chrome::FindBrowserWithProfile(profile_, chrome::GetActiveDesktop());
133 content::OpenURLParams(delegate_->GetLearnMoreUrl(),
136 content::PAGE_TRANSITION_LINK,
139 AcknowledgeExtensions();
140 delegate_->OnClose();
143 void ExtensionMessageBubbleController::AcknowledgeExtensions() {
144 ExtensionIdList* list = GetOrCreateExtensionList();
145 for (ExtensionIdList::const_iterator it = list->begin();
146 it != list->end(); ++it)
147 delegate_->AcknowledgeExtension(*it, user_action_);
150 ExtensionIdList* ExtensionMessageBubbleController::GetOrCreateExtensionList() {
152 scoped_ptr<const ExtensionSet> extension_set(
153 ExtensionRegistry::Get(profile_)->GenerateInstalledExtensionsSet());
154 for (ExtensionSet::const_iterator it = extension_set->begin();
155 it != extension_set->end(); ++it) {
156 std::string id = (*it)->id();
157 if (!delegate_->ShouldIncludeExtension(id))
159 extension_list_.push_back(id);
162 delegate_->LogExtensionCount(extension_list_.size());
166 return &extension_list_;
169 } // namespace extensions