app_list: Re-enable people search.
[chromium-blink-merge.git] / chrome / browser / extensions / settings_api_bubble_controller.cc
blobe89f42f129033152457ea5d93a2587c2347aeaa3
1 // Copyright (c) 2014 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/settings_api_bubble_controller.h"
7 #include "base/metrics/histogram.h"
8 #include "chrome/browser/extensions/extension_service.h"
9 #include "chrome/browser/extensions/extension_toolbar_model.h"
10 #include "chrome/browser/extensions/settings_api_helpers.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/ui/startup/startup_browser_creator.h"
13 #include "chrome/common/extensions/manifest_handlers/settings_overrides_handler.h"
14 #include "chrome/common/url_constants.h"
15 #include "chrome/grit/chromium_strings.h"
16 #include "chrome/grit/generated_resources.h"
17 #include "extensions/browser/extension_prefs.h"
18 #include "extensions/browser/extension_registry.h"
19 #include "extensions/browser/extension_system.h"
20 #include "grit/components_strings.h"
21 #include "ui/base/l10n/l10n_util.h"
23 namespace extensions {
25 namespace {
27 // Whether the user has been notified about extension taking over some aspect of
28 // the user's settings (homepage, startup pages, or search engine).
29 const char kSettingsBubbleAcknowledged[] = "ack_settings_bubble";
31 ////////////////////////////////////////////////////////////////////////////////
32 // SettingsApiBubbleDelegate
34 class SettingsApiBubbleDelegate
35 : public ExtensionMessageBubbleController::Delegate {
36 public:
37 explicit SettingsApiBubbleDelegate(ExtensionService* service,
38 Profile* profile,
39 SettingsApiOverrideType type);
40 ~SettingsApiBubbleDelegate() override;
42 // ExtensionMessageBubbleController::Delegate methods.
43 bool ShouldIncludeExtension(const std::string& extension_id) override;
44 void AcknowledgeExtension(
45 const std::string& extension_id,
46 ExtensionMessageBubbleController::BubbleAction user_action) override;
47 void PerformAction(const ExtensionIdList& list) override;
48 void OnClose() override;
49 base::string16 GetTitle() const override;
50 base::string16 GetMessageBody(bool anchored_to_browser_action) const override;
51 base::string16 GetOverflowText(
52 const base::string16& overflow_count) const override;
53 GURL GetLearnMoreUrl() const override;
54 base::string16 GetActionButtonLabel() const override;
55 base::string16 GetDismissButtonLabel() const override;
56 bool ShouldShowExtensionList() const override;
57 void LogExtensionCount(size_t count) override;
58 void LogAction(
59 ExtensionMessageBubbleController::BubbleAction action) override;
61 private:
62 // Our extension service. Weak, not owned by us.
63 ExtensionService* service_;
65 // A weak pointer to the profile we are associated with. Not owned by us.
66 Profile* profile_;
68 // The type of settings override this bubble will report on. This can be, for
69 // example, a bubble to notify the user that the search engine has been
70 // changed by an extension (or homepage/startup pages/etc).
71 SettingsApiOverrideType type_;
73 // The ID of the extension we are showing the bubble for.
74 std::string extension_id_;
76 DISALLOW_COPY_AND_ASSIGN(SettingsApiBubbleDelegate);
79 SettingsApiBubbleDelegate::SettingsApiBubbleDelegate(
80 ExtensionService* service,
81 Profile* profile,
82 SettingsApiOverrideType type)
83 : ExtensionMessageBubbleController::Delegate(profile),
84 service_(service),
85 type_(type) {
86 set_acknowledged_flag_pref_name(kSettingsBubbleAcknowledged);
89 SettingsApiBubbleDelegate::~SettingsApiBubbleDelegate() {}
91 bool SettingsApiBubbleDelegate::ShouldIncludeExtension(
92 const std::string& extension_id) {
93 ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
94 const Extension* extension =
95 registry->GetExtensionById(extension_id, ExtensionRegistry::ENABLED);
96 if (!extension)
97 return false; // The extension provided is no longer enabled.
99 if (HasBubbleInfoBeenAcknowledged(extension_id))
100 return false;
102 const Extension* override = NULL;
103 switch (type_) {
104 case extensions::BUBBLE_TYPE_HOME_PAGE:
105 override = extensions::GetExtensionOverridingHomepage(profile());
106 break;
107 case extensions::BUBBLE_TYPE_STARTUP_PAGES:
108 override = extensions::GetExtensionOverridingStartupPages(profile());
109 break;
110 case extensions::BUBBLE_TYPE_SEARCH_ENGINE:
111 override = extensions::GetExtensionOverridingSearchEngine(profile());
112 break;
115 if (!override || override->id() != extension->id())
116 return false;
118 extension_id_ = extension_id;
119 return true;
122 void SettingsApiBubbleDelegate::AcknowledgeExtension(
123 const std::string& extension_id,
124 ExtensionMessageBubbleController::BubbleAction user_action) {
125 if (user_action != ExtensionMessageBubbleController::ACTION_EXECUTE)
126 SetBubbleInfoBeenAcknowledged(extension_id, true);
129 void SettingsApiBubbleDelegate::PerformAction(const ExtensionIdList& list) {
130 for (size_t i = 0; i < list.size(); ++i) {
131 service_->DisableExtension(list[i], Extension::DISABLE_USER_ACTION);
135 void SettingsApiBubbleDelegate::OnClose() {
136 ExtensionToolbarModel* toolbar_model = ExtensionToolbarModel::Get(profile());
137 if (toolbar_model)
138 toolbar_model->StopHighlighting();
141 base::string16 SettingsApiBubbleDelegate::GetTitle() const {
142 switch (type_) {
143 case BUBBLE_TYPE_HOME_PAGE:
144 return l10n_util::GetStringUTF16(
145 IDS_EXTENSIONS_SETTINGS_API_TITLE_HOME_PAGE_BUBBLE);
146 case BUBBLE_TYPE_STARTUP_PAGES:
147 return l10n_util::GetStringUTF16(
148 IDS_EXTENSIONS_SETTINGS_API_TITLE_STARTUP_PAGES_BUBBLE);
149 case BUBBLE_TYPE_SEARCH_ENGINE:
150 return l10n_util::GetStringUTF16(
151 IDS_EXTENSIONS_SETTINGS_API_TITLE_SEARCH_ENGINE_BUBBLE);
153 NOTREACHED();
154 return base::string16();
157 base::string16 SettingsApiBubbleDelegate::GetMessageBody(
158 bool anchored_to_browser_action) const {
159 ExtensionRegistry* registry = ExtensionRegistry::Get(profile());
160 const Extension* extension =
161 registry->GetExtensionById(extension_id_, ExtensionRegistry::ENABLED);
162 const SettingsOverrides* settings =
163 extension ? SettingsOverrides::Get(extension) : NULL;
164 if (!extension || !settings) {
165 NOTREACHED();
166 return base::string16();
169 bool home_change = settings->homepage != NULL;
170 bool startup_change = !settings->startup_pages.empty();
171 bool search_change = settings->search_engine != NULL;
173 base::string16 body;
174 switch (type_) {
175 case BUBBLE_TYPE_HOME_PAGE:
176 body = l10n_util::GetStringUTF16(
177 IDS_EXTENSIONS_SETTINGS_API_FIRST_LINE_HOME_PAGE);
178 if (startup_change && search_change) {
179 body += l10n_util::GetStringUTF16(
180 IDS_EXTENSIONS_SETTINGS_API_SECOND_LINE_START_AND_SEARCH);
181 } else if (startup_change) {
182 body += l10n_util::GetStringUTF16(
183 IDS_EXTENSIONS_SETTINGS_API_SECOND_LINE_START_PAGES);
184 } else if (search_change) {
185 body += l10n_util::GetStringUTF16(
186 IDS_EXTENSIONS_SETTINGS_API_SECOND_LINE_SEARCH_ENGINE);
188 break;
189 case BUBBLE_TYPE_STARTUP_PAGES:
190 body = l10n_util::GetStringUTF16(
191 IDS_EXTENSIONS_SETTINGS_API_FIRST_LINE_START_PAGES);
192 if (home_change && search_change) {
193 body += l10n_util::GetStringUTF16(
194 IDS_EXTENSIONS_SETTINGS_API_SECOND_LINE_HOME_AND_SEARCH);
195 } else if (home_change) {
196 body += l10n_util::GetStringUTF16(
197 IDS_EXTENSIONS_SETTINGS_API_SECOND_LINE_HOME_PAGE);
198 } else if (search_change) {
199 body += l10n_util::GetStringUTF16(
200 IDS_EXTENSIONS_SETTINGS_API_SECOND_LINE_SEARCH_ENGINE);
202 break;
203 case BUBBLE_TYPE_SEARCH_ENGINE:
204 body = l10n_util::GetStringUTF16(
205 IDS_EXTENSIONS_SETTINGS_API_FIRST_LINE_SEARCH_ENGINE);
206 if (startup_change && home_change) {
207 body += l10n_util::GetStringUTF16(
208 IDS_EXTENSIONS_SETTINGS_API_SECOND_LINE_START_AND_HOME);
209 } else if (startup_change) {
210 body += l10n_util::GetStringUTF16(
211 IDS_EXTENSIONS_SETTINGS_API_SECOND_LINE_START_PAGES);
212 } else if (home_change) {
213 body += l10n_util::GetStringUTF16(
214 IDS_EXTENSIONS_SETTINGS_API_SECOND_LINE_HOME_PAGE);
216 break;
218 if (!body.empty())
219 body += l10n_util::GetStringUTF16(
220 IDS_EXTENSIONS_SETTINGS_API_THIRD_LINE_CONFIRMATION);
221 return body;
224 base::string16 SettingsApiBubbleDelegate::GetOverflowText(
225 const base::string16& overflow_count) const {
226 // Does not have more than one extension in the list at a time.
227 NOTREACHED();
228 return base::string16();
231 GURL SettingsApiBubbleDelegate::GetLearnMoreUrl() const {
232 return GURL(chrome::kExtensionControlledSettingLearnMoreURL);
235 base::string16 SettingsApiBubbleDelegate::GetActionButtonLabel() const {
236 return l10n_util::GetStringUTF16(IDS_EXTENSION_CONTROLLED_RESTORE_SETTINGS);
239 base::string16 SettingsApiBubbleDelegate::GetDismissButtonLabel() const {
240 return l10n_util::GetStringUTF16(IDS_EXTENSION_CONTROLLED_KEEP_CHANGES);
243 bool SettingsApiBubbleDelegate::ShouldShowExtensionList() const {
244 return false;
247 void SettingsApiBubbleDelegate::LogExtensionCount(size_t count) {
250 void SettingsApiBubbleDelegate::LogAction(
251 ExtensionMessageBubbleController::BubbleAction action) {
252 switch (type_) {
253 case BUBBLE_TYPE_HOME_PAGE:
254 UMA_HISTOGRAM_ENUMERATION(
255 "ExtensionOverrideBubble.SettingsApiUserSelectionHomePage",
256 action,
257 ExtensionMessageBubbleController::ACTION_BOUNDARY);
258 break;
259 case BUBBLE_TYPE_STARTUP_PAGES:
260 UMA_HISTOGRAM_ENUMERATION(
261 "ExtensionOverrideBubble.SettingsApiUserSelectionStartupPage",
262 action,
263 ExtensionMessageBubbleController::ACTION_BOUNDARY);
264 break;
265 case BUBBLE_TYPE_SEARCH_ENGINE:
266 UMA_HISTOGRAM_ENUMERATION(
267 "ExtensionOverrideBubble.SettingsApiUserSelectionSearchEngine",
268 action,
269 ExtensionMessageBubbleController::ACTION_BOUNDARY);
270 break;
274 } // namespace
276 ////////////////////////////////////////////////////////////////////////////////
277 // SettingsApiBubbleController
279 SettingsApiBubbleController::SettingsApiBubbleController(
280 Profile* profile,
281 SettingsApiOverrideType type)
282 : ExtensionMessageBubbleController(
283 new SettingsApiBubbleDelegate(
284 ExtensionSystem::Get(profile)->extension_service(),
285 profile,
286 type),
287 profile),
288 profile_(profile),
289 type_(type) {}
291 SettingsApiBubbleController::~SettingsApiBubbleController() {}
293 bool SettingsApiBubbleController::ShouldShow(const std::string& extension_id) {
294 if (delegate()->HasBubbleInfoBeenAcknowledged(extension_id))
295 return false;
297 if (!delegate()->ShouldIncludeExtension(extension_id))
298 return false;
300 // If the browser is showing the 'Chrome crashed' infobar, it won't be showing
301 // the startup pages, so there's no point in showing the bubble now.
302 if (type_ == BUBBLE_TYPE_STARTUP_PAGES)
303 return profile_->GetLastSessionExitType() != Profile::EXIT_CRASHED;
305 return true;
308 bool SettingsApiBubbleController::CloseOnDeactivate() {
309 // Startup bubbles tend to get lost in the focus storm that happens on
310 // startup. Other types should dismiss on focus loss.
311 return type_ != BUBBLE_TYPE_STARTUP_PAGES;
314 } // namespace extensions