Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / extension_message_bubble_controller.cc
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/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
18 namespace extensions {
19
20 ////////////////////////////////////////////////////////////////////////////////
21 // ExtensionMessageBubbleController::Delegate
22
23 ExtensionMessageBubbleController::Delegate::Delegate() {
24 }
25
26 ExtensionMessageBubbleController::Delegate::~Delegate() {
27 }
28
29 void ExtensionMessageBubbleController::Delegate::RestrictToSingleExtension(
30     const std::string& extension_id) {
31   NOTIMPLEMENTED();  // Derived classes that need this should implement.
32 }
33
34 ////////////////////////////////////////////////////////////////////////////////
35 // ExtensionMessageBubbleController
36
37 ExtensionMessageBubbleController::ExtensionMessageBubbleController(
38     Delegate* delegate, Profile* profile)
39     : profile_(profile),
40       user_action_(ACTION_BOUNDARY),
41       delegate_(delegate),
42       initialized_(false) {
43 }
44
45 ExtensionMessageBubbleController::~ExtensionMessageBubbleController() {
46 }
47
48 std::vector<base::string16>
49 ExtensionMessageBubbleController::GetExtensionList() {
50   ExtensionIdList* list = GetOrCreateExtensionList();
51   if (list->empty())
52     return std::vector<base::string16>();
53
54   ExtensionRegistry* registry = ExtensionRegistry::Get(profile_);
55   std::vector<base::string16> return_value;
56   for (ExtensionIdList::const_iterator it = list->begin();
57        it != list->end(); ++it) {
58     const Extension* extension =
59         registry->GetExtensionById(*it, ExtensionRegistry::EVERYTHING);
60     if (extension) {
61       return_value.push_back(base::UTF8ToUTF16(extension->name()));
62     } else {
63       return_value.push_back(
64           base::ASCIIToUTF16(std::string("(unknown name) ") + *it));
65       // TODO(finnur): Add this as a string to the grd, for next milestone.
66     }
67   }
68   return return_value;
69 }
70
71 const ExtensionIdList& ExtensionMessageBubbleController::GetExtensionIdList() {
72   return *GetOrCreateExtensionList();
73 }
74
75 bool ExtensionMessageBubbleController::CloseOnDeactivate() { return false; }
76
77 void ExtensionMessageBubbleController::Show(ExtensionMessageBubble* bubble) {
78   // Wire up all the callbacks, to get notified what actions the user took.
79   base::Closure dismiss_button_callback =
80       base::Bind(&ExtensionMessageBubbleController::OnBubbleDismiss,
81       base::Unretained(this));
82   base::Closure action_button_callback =
83       base::Bind(&ExtensionMessageBubbleController::OnBubbleAction,
84       base::Unretained(this));
85   base::Closure link_callback =
86       base::Bind(&ExtensionMessageBubbleController::OnLinkClicked,
87       base::Unretained(this));
88   bubble->OnActionButtonClicked(action_button_callback);
89   bubble->OnDismissButtonClicked(dismiss_button_callback);
90   bubble->OnLinkClicked(link_callback);
91
92   bubble->Show();
93 }
94
95 void ExtensionMessageBubbleController::OnBubbleAction() {
96   DCHECK_EQ(ACTION_BOUNDARY, user_action_);
97   user_action_ = ACTION_EXECUTE;
98
99   delegate_->LogAction(ACTION_EXECUTE);
100   delegate_->PerformAction(*GetOrCreateExtensionList());
101   AcknowledgeExtensions();
102   delegate_->OnClose();
103 }
104
105 void ExtensionMessageBubbleController::OnBubbleDismiss() {
106   // OnBubbleDismiss() can be called twice when we receive multiple
107   // "OnWidgetDestroying" notifications (this can at least happen when we close
108   // a window with a notification open). Handle this gracefully.
109   if (user_action_ != ACTION_BOUNDARY) {
110     DCHECK(user_action_ == ACTION_DISMISS);
111     return;
112   }
113
114   user_action_ = ACTION_DISMISS;
115
116   delegate_->LogAction(ACTION_DISMISS);
117   AcknowledgeExtensions();
118   delegate_->OnClose();
119 }
120
121 void ExtensionMessageBubbleController::OnLinkClicked() {
122   DCHECK_EQ(ACTION_BOUNDARY, user_action_);
123   user_action_ = ACTION_LEARN_MORE;
124
125   delegate_->LogAction(ACTION_LEARN_MORE);
126   Browser* browser =
127       chrome::FindBrowserWithProfile(profile_, chrome::GetActiveDesktop());
128   if (browser) {
129     browser->OpenURL(
130         content::OpenURLParams(delegate_->GetLearnMoreUrl(),
131                                content::Referrer(),
132                                NEW_FOREGROUND_TAB,
133                                ui::PAGE_TRANSITION_LINK,
134                                false));
135   }
136   AcknowledgeExtensions();
137   delegate_->OnClose();
138 }
139
140 void ExtensionMessageBubbleController::AcknowledgeExtensions() {
141   ExtensionIdList* list = GetOrCreateExtensionList();
142   for (ExtensionIdList::const_iterator it = list->begin();
143        it != list->end(); ++it)
144     delegate_->AcknowledgeExtension(*it, user_action_);
145 }
146
147 ExtensionIdList* ExtensionMessageBubbleController::GetOrCreateExtensionList() {
148   if (!initialized_) {
149     scoped_ptr<const ExtensionSet> extension_set(
150         ExtensionRegistry::Get(profile_)->GenerateInstalledExtensionsSet());
151     for (ExtensionSet::const_iterator it = extension_set->begin();
152          it != extension_set->end(); ++it) {
153       std::string id = (*it)->id();
154       if (!delegate_->ShouldIncludeExtension(id))
155         continue;
156       extension_list_.push_back(id);
157     }
158
159     delegate_->LogExtensionCount(extension_list_.size());
160     initialized_ = true;
161   }
162
163   return &extension_list_;
164 }
165
166 }  // namespace extensions