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/suspicious_extension_bubble_controller.h" 6 7#include "base/lazy_instance.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_service.h" 12#include "chrome/browser/profiles/profile.h" 13#include "chrome/browser/ui/browser.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_system.h" 19#include "extensions/common/extension.h" 20#include "grit/components_strings.h" 21#include "ui/base/l10n/l10n_util.h" 22 23using extensions::ExtensionMessageBubbleController; 24 25namespace { 26 27base::LazyInstance<std::set<Profile*> > g_shown_for_profiles = 28 LAZY_INSTANCE_INITIALIZER; 29 30//////////////////////////////////////////////////////////////////////////////// 31// SuspiciousExtensionBubbleDelegate 32 33class SuspiciousExtensionBubbleDelegate 34 : public ExtensionMessageBubbleController::Delegate { 35 public: 36 explicit SuspiciousExtensionBubbleDelegate(Profile* profile); 37 virtual ~SuspiciousExtensionBubbleDelegate(); 38 39 // ExtensionMessageBubbleController::Delegate methods. 40 virtual bool ShouldIncludeExtension(const std::string& extension_id) OVERRIDE; 41 virtual void AcknowledgeExtension( 42 const std::string& extension_id, 43 ExtensionMessageBubbleController::BubbleAction user_action) OVERRIDE; 44 virtual void PerformAction(const extensions::ExtensionIdList& list) OVERRIDE; 45 virtual base::string16 GetTitle() const OVERRIDE; 46 virtual base::string16 GetMessageBody( 47 bool anchored_to_browser_action) const OVERRIDE; 48 virtual base::string16 GetOverflowText( 49 const base::string16& overflow_count) const OVERRIDE; 50 virtual base::string16 GetLearnMoreLabel() const OVERRIDE; 51 virtual GURL GetLearnMoreUrl() const OVERRIDE; 52 virtual base::string16 GetActionButtonLabel() const OVERRIDE; 53 virtual base::string16 GetDismissButtonLabel() const OVERRIDE; 54 virtual bool ShouldShowExtensionList() const OVERRIDE; 55 virtual void LogExtensionCount(size_t count) OVERRIDE; 56 virtual void LogAction( 57 ExtensionMessageBubbleController::BubbleAction action) OVERRIDE; 58 59 private: 60 // Our profile. Weak, not owned by us. 61 Profile* profile_; 62 63 DISALLOW_COPY_AND_ASSIGN(SuspiciousExtensionBubbleDelegate); 64}; 65 66SuspiciousExtensionBubbleDelegate::SuspiciousExtensionBubbleDelegate( 67 Profile* profile) 68 : profile_(profile) {} 69 70SuspiciousExtensionBubbleDelegate::~SuspiciousExtensionBubbleDelegate() { 71} 72 73bool SuspiciousExtensionBubbleDelegate::ShouldIncludeExtension( 74 const std::string& extension_id) { 75 extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(profile_); 76 if (!prefs->IsExtensionDisabled(extension_id)) 77 return false; 78 79 int disble_reasons = prefs->GetDisableReasons(extension_id); 80 if (disble_reasons & extensions::Extension::DISABLE_NOT_VERIFIED) 81 return !prefs->HasWipeoutBeenAcknowledged(extension_id); 82 83 return false; 84} 85 86void SuspiciousExtensionBubbleDelegate::AcknowledgeExtension( 87 const std::string& extension_id, 88 ExtensionMessageBubbleController::BubbleAction user_action) { 89 extensions::ExtensionPrefs* prefs = extensions::ExtensionPrefs::Get(profile_); 90 prefs->SetWipeoutAcknowledged(extension_id, true); 91} 92 93void SuspiciousExtensionBubbleDelegate::PerformAction( 94 const extensions::ExtensionIdList& list) { 95 // This bubble solicits no action from the user. Or as Nimoy would have it: 96 // "Well, my work here is done". 97} 98 99base::string16 SuspiciousExtensionBubbleDelegate::GetTitle() const { 100 return l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNSUPPORTED_DISABLED_TITLE); 101} 102 103base::string16 SuspiciousExtensionBubbleDelegate::GetMessageBody( 104 bool anchored_to_browser_action) const { 105 return l10n_util::GetStringFUTF16(IDS_EXTENSIONS_UNSUPPORTED_DISABLED_BODY, 106 l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE)); 107} 108 109base::string16 SuspiciousExtensionBubbleDelegate::GetOverflowText( 110 const base::string16& overflow_count) const { 111 return l10n_util::GetStringFUTF16( 112 IDS_EXTENSIONS_DISABLED_AND_N_MORE, 113 overflow_count); 114} 115 116base::string16 117SuspiciousExtensionBubbleDelegate::GetLearnMoreLabel() const { 118 return l10n_util::GetStringUTF16(IDS_LEARN_MORE); 119} 120 121GURL SuspiciousExtensionBubbleDelegate::GetLearnMoreUrl() const { 122 return GURL(chrome::kRemoveNonCWSExtensionURL); 123} 124 125base::string16 126SuspiciousExtensionBubbleDelegate::GetActionButtonLabel() const { 127 return base::string16(); 128} 129 130base::string16 131SuspiciousExtensionBubbleDelegate::GetDismissButtonLabel() const { 132 return l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNSUPPORTED_DISABLED_BUTTON); 133} 134 135bool 136SuspiciousExtensionBubbleDelegate::ShouldShowExtensionList() const { 137 return true; 138} 139 140void SuspiciousExtensionBubbleDelegate::LogExtensionCount( 141 size_t count) { 142 UMA_HISTOGRAM_COUNTS_100( 143 "ExtensionBubble.ExtensionWipeoutCount", count); 144} 145 146void SuspiciousExtensionBubbleDelegate::LogAction( 147 ExtensionMessageBubbleController::BubbleAction action) { 148 UMA_HISTOGRAM_ENUMERATION( 149 "ExtensionBubble.WipeoutUserSelection", 150 action, ExtensionMessageBubbleController::ACTION_BOUNDARY); 151} 152 153} // namespace 154 155namespace extensions { 156 157//////////////////////////////////////////////////////////////////////////////// 158// SuspiciousExtensionBubbleController 159 160// static 161void SuspiciousExtensionBubbleController::ClearProfileListForTesting() { 162 g_shown_for_profiles.Get().clear(); 163} 164 165SuspiciousExtensionBubbleController::SuspiciousExtensionBubbleController( 166 Profile* profile) 167 : ExtensionMessageBubbleController( 168 new SuspiciousExtensionBubbleDelegate(profile), 169 profile), 170 profile_(profile) {} 171 172SuspiciousExtensionBubbleController::~SuspiciousExtensionBubbleController() { 173} 174 175bool SuspiciousExtensionBubbleController::ShouldShow() { 176 return !g_shown_for_profiles.Get().count(profile_->GetOriginalProfile()) && 177 !GetExtensionList().empty(); 178} 179 180void SuspiciousExtensionBubbleController::Show(ExtensionMessageBubble* bubble) { 181 g_shown_for_profiles.Get().insert(profile_->GetOriginalProfile()); 182 ExtensionMessageBubbleController::Show(bubble); 183} 184 185} // namespace extensions 186