Home | History | Annotate | Download | only in extensions
      1 // Copyright 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/proxy_overridden_bubble_controller.h"
      6 
      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/common/url_constants.h"
     13 #include "chrome/grit/generated_resources.h"
     14 #include "extensions/browser/extension_registry.h"
     15 #include "extensions/browser/extension_system.h"
     16 #include "grit/components_strings.h"
     17 #include "ui/base/l10n/l10n_util.h"
     18 
     19 namespace extensions {
     20 
     21 namespace {
     22 
     23 // The minimum time to wait (since the extension was installed) before notifying
     24 // the user about it.
     25 const int kDaysSinceInstallMin = 7;
     26 
     27 ////////////////////////////////////////////////////////////////////////////////
     28 // ProxyOverriddenBubbleDelegate
     29 
     30 class ProxyOverriddenBubbleDelegate
     31     : public ExtensionMessageBubbleController::Delegate {
     32  public:
     33   ProxyOverriddenBubbleDelegate(ExtensionService* service, Profile* profile);
     34   virtual ~ProxyOverriddenBubbleDelegate();
     35 
     36   // ExtensionMessageBubbleController::Delegate methods.
     37   virtual bool ShouldIncludeExtension(const std::string& extension_id) OVERRIDE;
     38   virtual void AcknowledgeExtension(
     39       const std::string& extension_id,
     40       ExtensionMessageBubbleController::BubbleAction
     41           user_action) OVERRIDE;
     42   virtual void PerformAction(const ExtensionIdList& list) OVERRIDE;
     43   virtual void OnClose() OVERRIDE;
     44   virtual base::string16 GetTitle() const OVERRIDE;
     45   virtual base::string16 GetMessageBody(
     46       bool anchored_to_browser_action) const OVERRIDE;
     47   virtual base::string16 GetOverflowText(
     48       const base::string16& overflow_count) const OVERRIDE;
     49   virtual base::string16 GetLearnMoreLabel() const OVERRIDE;
     50   virtual GURL GetLearnMoreUrl() const OVERRIDE;
     51   virtual base::string16 GetActionButtonLabel() const OVERRIDE;
     52   virtual base::string16 GetDismissButtonLabel() const OVERRIDE;
     53   virtual bool ShouldShowExtensionList() const OVERRIDE;
     54   virtual void RestrictToSingleExtension(
     55       const std::string& extension_id) OVERRIDE;
     56   virtual void LogExtensionCount(size_t count) OVERRIDE;
     57   virtual void LogAction(
     58       ExtensionMessageBubbleController::BubbleAction
     59           action) OVERRIDE;
     60 
     61  private:
     62   // Our extension service. Weak, not owned by us.
     63   ExtensionService* service_;
     64 
     65   // A weak pointer to the profile we are associated with. Not owned by us.
     66   Profile* profile_;
     67 
     68   // The ID of the extension we are showing the bubble for.
     69   std::string extension_id_;
     70 
     71   DISALLOW_COPY_AND_ASSIGN(ProxyOverriddenBubbleDelegate);
     72 };
     73 
     74 ProxyOverriddenBubbleDelegate::ProxyOverriddenBubbleDelegate(
     75     ExtensionService* service,
     76     Profile* profile)
     77     : service_(service), profile_(profile) {}
     78 
     79 ProxyOverriddenBubbleDelegate::~ProxyOverriddenBubbleDelegate() {}
     80 
     81 bool ProxyOverriddenBubbleDelegate::ShouldIncludeExtension(
     82     const std::string& extension_id) {
     83   if (!extension_id_.empty() && extension_id_ != extension_id)
     84     return false;
     85 
     86   const Extension* extension =
     87       ExtensionRegistry::Get(profile_)->enabled_extensions().GetByID(
     88           extension_id);
     89   if (!extension)
     90     return false;  // The extension provided is no longer enabled.
     91 
     92   const Extension* overriding = GetExtensionOverridingProxy(profile_);
     93   if (!overriding || overriding->id() != extension_id)
     94     return false;
     95 
     96   ExtensionPrefs* prefs = ExtensionPrefs::Get(profile_);
     97   base::TimeDelta since_install =
     98       base::Time::Now() - prefs->GetInstallTime(extension->id());
     99   if (since_install.InDays() < kDaysSinceInstallMin)
    100     return false;
    101 
    102   if (ExtensionPrefs::Get(profile_)->HasProxyOverriddenBubbleBeenAcknowledged(
    103       extension_id))
    104     return false;
    105 
    106   return true;
    107 }
    108 
    109 void ProxyOverriddenBubbleDelegate::AcknowledgeExtension(
    110     const std::string& extension_id,
    111     ExtensionMessageBubbleController::BubbleAction user_action) {
    112   if (user_action != ExtensionMessageBubbleController::ACTION_EXECUTE) {
    113     ExtensionPrefs::Get(profile_)->SetProxyOverriddenBubbleBeenAcknowledged(
    114         extension_id, true);
    115   }
    116 }
    117 
    118 void ProxyOverriddenBubbleDelegate::PerformAction(const ExtensionIdList& list) {
    119   for (size_t i = 0; i < list.size(); ++i)
    120     service_->DisableExtension(list[i], Extension::DISABLE_USER_ACTION);
    121 }
    122 
    123 void ProxyOverriddenBubbleDelegate::OnClose() {
    124   ExtensionToolbarModel* toolbar_model =
    125       ExtensionToolbarModel::Get(profile_);
    126   if (toolbar_model)
    127     toolbar_model->StopHighlighting();
    128 }
    129 
    130 base::string16 ProxyOverriddenBubbleDelegate::GetTitle() const {
    131   return l10n_util::GetStringUTF16(
    132       IDS_EXTENSIONS_PROXY_CONTROLLED_TITLE_HOME_PAGE_BUBBLE);
    133 }
    134 
    135 base::string16 ProxyOverriddenBubbleDelegate::GetMessageBody(
    136     bool anchored_to_browser_action) const {
    137   if (anchored_to_browser_action) {
    138     return l10n_util::GetStringUTF16(
    139         IDS_EXTENSIONS_PROXY_CONTROLLED_FIRST_LINE_EXTENSION_SPECIFIC);
    140   } else {
    141     return l10n_util::GetStringUTF16(
    142         IDS_EXTENSIONS_PROXY_CONTROLLED_FIRST_LINE);
    143   }
    144 }
    145 
    146 base::string16 ProxyOverriddenBubbleDelegate::GetOverflowText(
    147     const base::string16& overflow_count) const {
    148   // Does not have more than one extension in the list at a time.
    149   NOTREACHED();
    150   return base::string16();
    151 }
    152 
    153 base::string16 ProxyOverriddenBubbleDelegate::GetLearnMoreLabel() const {
    154   return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
    155 }
    156 
    157 GURL ProxyOverriddenBubbleDelegate::GetLearnMoreUrl() const {
    158   return GURL(chrome::kExtensionControlledSettingLearnMoreURL);
    159 }
    160 
    161 base::string16 ProxyOverriddenBubbleDelegate::GetActionButtonLabel() const {
    162   return l10n_util::GetStringUTF16(IDS_EXTENSION_CONTROLLED_RESTORE_SETTINGS);
    163 }
    164 
    165 base::string16 ProxyOverriddenBubbleDelegate::GetDismissButtonLabel() const {
    166   return l10n_util::GetStringUTF16(IDS_EXTENSION_CONTROLLED_KEEP_CHANGES);
    167 }
    168 
    169 bool ProxyOverriddenBubbleDelegate::ShouldShowExtensionList() const {
    170   return false;
    171 }
    172 
    173 void ProxyOverriddenBubbleDelegate::RestrictToSingleExtension(
    174     const std::string& extension_id) {
    175   extension_id_ = extension_id;
    176 }
    177 
    178 void ProxyOverriddenBubbleDelegate::LogExtensionCount(size_t count) {
    179   UMA_HISTOGRAM_COUNTS_100("ProxyOverriddenBubble.ExtensionCount", count);
    180 }
    181 
    182 void ProxyOverriddenBubbleDelegate::LogAction(
    183     ExtensionMessageBubbleController::BubbleAction action) {
    184   UMA_HISTOGRAM_ENUMERATION("ProxyOverriddenBubble.UserSelection",
    185                             action,
    186                             ExtensionMessageBubbleController::ACTION_BOUNDARY);
    187 }
    188 
    189 }  // namespace
    190 
    191 ////////////////////////////////////////////////////////////////////////////////
    192 // ProxyOverriddenBubbleController
    193 
    194 ProxyOverriddenBubbleController::ProxyOverriddenBubbleController(
    195     Profile* profile)
    196     : ExtensionMessageBubbleController(
    197           new ProxyOverriddenBubbleDelegate(
    198               ExtensionSystem::Get(profile)->extension_service(),
    199               profile),
    200           profile),
    201       profile_(profile) {}
    202 
    203 ProxyOverriddenBubbleController::~ProxyOverriddenBubbleController() {}
    204 
    205 bool ProxyOverriddenBubbleController::ShouldShow(
    206     const std::string& extension_id) {
    207   if (!delegate()->ShouldIncludeExtension(extension_id))
    208     return false;
    209 
    210   delegate()->RestrictToSingleExtension(extension_id);
    211   return true;
    212 }
    213 
    214 bool ProxyOverriddenBubbleController::CloseOnDeactivate() {
    215   return false;
    216 }
    217 
    218 }  // namespace extensions
    219