• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "chrome/browser/extensions/extension_message_bubble_controller.h"
6 
7 #include "base/bind.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/extensions/extension_prefs.h"
12 #include "chrome/browser/extensions/extension_service.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/browser_finder.h"
15 #include "chrome/common/url_constants.h"
16 #include "content/public/browser/user_metrics.h"
17 #include "grit/chromium_strings.h"
18 #include "grit/generated_resources.h"
19 #include "ui/base/l10n/l10n_util.h"
20 
21 namespace extensions {
22 
23 ////////////////////////////////////////////////////////////////////////////////
24 // ExtensionMessageBubbleController
25 
ExtensionMessageBubbleController(Delegate * delegate,Profile * profile)26 ExtensionMessageBubbleController::ExtensionMessageBubbleController(
27     Delegate* delegate, Profile* profile)
28     : service_(extensions::ExtensionSystem::Get(profile)->extension_service()),
29       profile_(profile),
30       user_action_(ACTION_BOUNDARY),
31       delegate_(delegate),
32       initialized_(false),
33       has_notified_(false) {
34 }
35 
~ExtensionMessageBubbleController()36 ExtensionMessageBubbleController::~ExtensionMessageBubbleController() {
37 }
38 
ShouldShow()39 bool ExtensionMessageBubbleController::ShouldShow() {
40   if (has_notified_)
41     return false;
42 
43   has_notified_ = true;
44   return !GetOrCreateExtensionList()->empty();
45 }
46 
47 std::vector<string16>
GetExtensionList()48 ExtensionMessageBubbleController::GetExtensionList() {
49   ExtensionIdList* list = GetOrCreateExtensionList();
50   if (list->empty())
51     return std::vector<string16>();
52 
53   std::vector<string16> return_value;
54   for (ExtensionIdList::const_iterator it = list->begin();
55        it != list->end(); ++it) {
56     const Extension* extension = service_->GetInstalledExtension(*it);
57     if (extension) {
58       return_value.push_back(UTF8ToUTF16(extension->name()));
59     } else {
60       return_value.push_back(
61           ASCIIToUTF16(std::string("(unknown name) ") + *it));
62       // TODO(finnur): Add this as a string to the grd, for next milestone.
63     }
64   }
65   return return_value;
66 }
67 
GetExtensionIdList()68 const ExtensionIdList& ExtensionMessageBubbleController::GetExtensionIdList() {
69   return *GetOrCreateExtensionList();
70 }
71 
Show(ExtensionMessageBubble * bubble)72 void ExtensionMessageBubbleController::Show(ExtensionMessageBubble* bubble) {
73   // Wire up all the callbacks, to get notified what actions the user took.
74   base::Closure dismiss_button_callback =
75       base::Bind(&ExtensionMessageBubbleController::OnBubbleDismiss,
76       base::Unretained(this));
77   base::Closure action_button_callback =
78       base::Bind(&ExtensionMessageBubbleController::OnBubbleAction,
79       base::Unretained(this));
80   base::Closure link_callback =
81       base::Bind(&ExtensionMessageBubbleController::OnLinkClicked,
82       base::Unretained(this));
83   bubble->OnActionButtonClicked(action_button_callback);
84   bubble->OnDismissButtonClicked(dismiss_button_callback);
85   bubble->OnLinkClicked(link_callback);
86 
87   bubble->Show();
88 }
89 
OnBubbleAction()90 void ExtensionMessageBubbleController::OnBubbleAction() {
91   DCHECK_EQ(ACTION_BOUNDARY, user_action_);
92   user_action_ = ACTION_EXECUTE;
93 
94   delegate_->LogAction(ACTION_EXECUTE);
95   delegate_->PerformAction(*GetOrCreateExtensionList());
96   AcknowledgeExtensions();
97 }
98 
OnBubbleDismiss()99 void ExtensionMessageBubbleController::OnBubbleDismiss() {
100   DCHECK_EQ(ACTION_BOUNDARY, user_action_);
101   user_action_ = ACTION_DISMISS;
102 
103   delegate_->LogAction(ACTION_DISMISS);
104   AcknowledgeExtensions();
105 }
106 
OnLinkClicked()107 void ExtensionMessageBubbleController::OnLinkClicked() {
108   DCHECK_EQ(ACTION_BOUNDARY, user_action_);
109   user_action_ = ACTION_LEARN_MORE;
110 
111   delegate_->LogAction(ACTION_LEARN_MORE);
112   Browser* browser =
113       chrome::FindBrowserWithProfile(profile_, chrome::GetActiveDesktop());
114   if (browser) {
115     browser->OpenURL(
116         content::OpenURLParams(delegate_->GetLearnMoreUrl(),
117                                content::Referrer(),
118                                NEW_FOREGROUND_TAB,
119                                content::PAGE_TRANSITION_LINK,
120                                false));
121   }
122   AcknowledgeExtensions();
123 }
124 
AcknowledgeExtensions()125 void ExtensionMessageBubbleController::AcknowledgeExtensions() {
126   ExtensionIdList* list = GetOrCreateExtensionList();
127   for (ExtensionIdList::const_iterator it = list->begin();
128        it != list->end(); ++it)
129     delegate_->AcknowledgeExtension(*it, user_action_);
130 }
131 
GetOrCreateExtensionList()132 ExtensionIdList* ExtensionMessageBubbleController::GetOrCreateExtensionList() {
133   if (!service_)
134     return &extension_list_;  // Can occur during testing.
135 
136   if (!initialized_) {
137     scoped_ptr<const ExtensionSet> extension_set(
138         service_->GenerateInstalledExtensionsSet());
139     for (ExtensionSet::const_iterator it = extension_set->begin();
140          it != extension_set->end(); ++it) {
141       std::string id = (*it)->id();
142       if (!delegate_->ShouldIncludeExtension(id))
143         continue;
144       extension_list_.push_back(id);
145     }
146 
147     delegate_->LogExtensionCount(extension_list_.size());
148     initialized_ = true;
149   }
150 
151   return &extension_list_;
152 }
153 
154 }  // namespace extensions
155