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.
4
5#include "chrome/browser/extensions/ntp_overridden_bubble_controller.h"
6
7#include "base/metrics/histogram.h"
8#include "chrome/browser/extensions/extension_service.h"
9#include "chrome/browser/profiles/profile.h"
10#include "chrome/common/url_constants.h"
11#include "chrome/grit/generated_resources.h"
12#include "extensions/browser/extension_prefs.h"
13#include "extensions/browser/extension_registry.h"
14#include "extensions/browser/extension_system.h"
15#include "grit/components_strings.h"
16#include "ui/base/l10n/l10n_util.h"
17
18using extensions::ExtensionMessageBubbleController;
19using extensions::NtpOverriddenBubbleController;
20
21namespace {
22
23////////////////////////////////////////////////////////////////////////////////
24// NtpOverriddenBubbleDelegate
25
26class NtpOverriddenBubbleDelegate
27    : public extensions::ExtensionMessageBubbleController::Delegate {
28 public:
29  NtpOverriddenBubbleDelegate(ExtensionService* service, Profile* profile);
30  virtual ~NtpOverriddenBubbleDelegate();
31
32  // ExtensionMessageBubbleController::Delegate methods.
33  virtual bool ShouldIncludeExtension(const std::string& extension_id) OVERRIDE;
34  virtual void AcknowledgeExtension(
35      const std::string& extension_id,
36      extensions::ExtensionMessageBubbleController::BubbleAction
37          user_action) OVERRIDE;
38  virtual void PerformAction(const extensions::ExtensionIdList& list) OVERRIDE;
39  virtual base::string16 GetTitle() const OVERRIDE;
40  virtual base::string16 GetMessageBody(
41      bool anchored_to_browser_action) const OVERRIDE;
42  virtual base::string16 GetOverflowText(
43      const base::string16& overflow_count) const OVERRIDE;
44  virtual base::string16 GetLearnMoreLabel() const OVERRIDE;
45  virtual GURL GetLearnMoreUrl() const OVERRIDE;
46  virtual base::string16 GetActionButtonLabel() const OVERRIDE;
47  virtual base::string16 GetDismissButtonLabel() const OVERRIDE;
48  virtual bool ShouldShowExtensionList() const OVERRIDE;
49  virtual void RestrictToSingleExtension(
50      const std::string& extension_id) OVERRIDE;
51  virtual void LogExtensionCount(size_t count) OVERRIDE;
52  virtual void LogAction(
53      extensions::ExtensionMessageBubbleController::BubbleAction
54          action) OVERRIDE;
55
56 private:
57  // Our extension service. Weak, not owned by us.
58  ExtensionService* service_;
59
60  // A weak pointer to the profile we are associated with. Not owned by us.
61  Profile* profile_;
62
63  // The ID of the extension we are showing the bubble for.
64  std::string extension_id_;
65
66  DISALLOW_COPY_AND_ASSIGN(NtpOverriddenBubbleDelegate);
67};
68
69NtpOverriddenBubbleDelegate::NtpOverriddenBubbleDelegate(
70    ExtensionService* service,
71    Profile* profile)
72    : service_(service), profile_(profile) {}
73
74NtpOverriddenBubbleDelegate::~NtpOverriddenBubbleDelegate() {}
75
76bool NtpOverriddenBubbleDelegate::ShouldIncludeExtension(
77    const std::string& extension_id) {
78  if (!extension_id_.empty() && extension_id_ != extension_id)
79    return false;
80
81  using extensions::ExtensionRegistry;
82  ExtensionRegistry* registry = ExtensionRegistry::Get(profile_);
83  const extensions::Extension* extension =
84      registry->GetExtensionById(extension_id, ExtensionRegistry::ENABLED);
85  if (!extension)
86    return false;  // The extension provided is no longer enabled.
87
88  extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(profile_);
89  if (prefs->HasNtpOverriddenBubbleBeenAcknowledged(extension_id))
90    return false;
91
92  return true;
93}
94
95void NtpOverriddenBubbleDelegate::AcknowledgeExtension(
96    const std::string& extension_id,
97    ExtensionMessageBubbleController::BubbleAction user_action) {
98  if (user_action != ExtensionMessageBubbleController::ACTION_EXECUTE) {
99    extensions::ExtensionPrefs* prefs =
100        extensions::ExtensionPrefs::Get(profile_);
101    prefs->SetNtpOverriddenBubbleBeenAcknowledged(extension_id, true);
102  }
103}
104
105void NtpOverriddenBubbleDelegate::PerformAction(
106    const extensions::ExtensionIdList& list) {
107  for (size_t i = 0; i < list.size(); ++i) {
108    service_->DisableExtension(list[i],
109                               extensions::Extension::DISABLE_USER_ACTION);
110  }
111}
112
113base::string16 NtpOverriddenBubbleDelegate::GetTitle() const {
114  return l10n_util::GetStringUTF16(
115      IDS_EXTENSIONS_NTP_CONTROLLED_TITLE_HOME_PAGE_BUBBLE);
116}
117
118base::string16 NtpOverriddenBubbleDelegate::GetMessageBody(
119    bool anchored_to_browser_action) const {
120  base::string16 body =
121      l10n_util::GetStringUTF16(IDS_EXTENSIONS_NTP_CONTROLLED_FIRST_LINE);
122  body += l10n_util::GetStringUTF16(
123      IDS_EXTENSIONS_SETTINGS_API_THIRD_LINE_CONFIRMATION);
124  return body;
125}
126
127base::string16 NtpOverriddenBubbleDelegate::GetOverflowText(
128    const base::string16& overflow_count) const {
129  // Does not have more than one extension in the list at a time.
130  NOTREACHED();
131  return base::string16();
132}
133
134base::string16 NtpOverriddenBubbleDelegate::GetLearnMoreLabel() const {
135  return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
136}
137
138GURL NtpOverriddenBubbleDelegate::GetLearnMoreUrl() const {
139  return GURL(chrome::kExtensionControlledSettingLearnMoreURL);
140}
141
142base::string16 NtpOverriddenBubbleDelegate::GetActionButtonLabel() const {
143  return l10n_util::GetStringUTF16(IDS_EXTENSION_CONTROLLED_RESTORE_SETTINGS);
144}
145
146base::string16 NtpOverriddenBubbleDelegate::GetDismissButtonLabel() const {
147  return l10n_util::GetStringUTF16(IDS_EXTENSION_CONTROLLED_KEEP_CHANGES);
148}
149
150bool NtpOverriddenBubbleDelegate::ShouldShowExtensionList() const {
151  return false;
152}
153
154void NtpOverriddenBubbleDelegate::RestrictToSingleExtension(
155    const std::string& extension_id) {
156  extension_id_ = extension_id;
157}
158
159void NtpOverriddenBubbleDelegate::LogExtensionCount(size_t count) {
160}
161
162void NtpOverriddenBubbleDelegate::LogAction(
163    ExtensionMessageBubbleController::BubbleAction action) {
164  UMA_HISTOGRAM_ENUMERATION(
165      "ExtensionOverrideBubble.NtpOverriddenUserSelection",
166      action,
167      ExtensionMessageBubbleController::ACTION_BOUNDARY);
168}
169
170}  // namespace
171
172namespace extensions {
173
174////////////////////////////////////////////////////////////////////////////////
175// NtpOverriddenBubbleController
176
177NtpOverriddenBubbleController::NtpOverriddenBubbleController(Profile* profile)
178    : ExtensionMessageBubbleController(
179          new NtpOverriddenBubbleDelegate(
180              ExtensionSystem::Get(profile)->extension_service(),
181              profile),
182          profile),
183      profile_(profile) {}
184
185NtpOverriddenBubbleController::~NtpOverriddenBubbleController() {}
186
187bool NtpOverriddenBubbleController::ShouldShow(
188    const std::string& extension_id) {
189  if (!delegate()->ShouldIncludeExtension(extension_id))
190    return false;
191
192  delegate()->RestrictToSingleExtension(extension_id);
193  return true;
194}
195
196bool NtpOverriddenBubbleController::CloseOnDeactivate() {
197  return true;
198}
199
200}  // namespace extensions
201