| Index: chrome/browser/extensions/extension_message_bubble_controller.cc
|
| diff --git a/chrome/browser/extensions/extension_message_bubble_controller.cc b/chrome/browser/extensions/extension_message_bubble_controller.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6dcfa81d2c2f8dafb434f87a83610774a5e7f99a
|
| --- /dev/null
|
| +++ b/chrome/browser/extensions/extension_message_bubble_controller.cc
|
| @@ -0,0 +1,256 @@
|
| +// Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/browser/extensions/extension_message_bubble_controller.h"
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/metrics/histogram.h"
|
| +#include "base/strings/utf_string_conversions.h"
|
| +#include "chrome/browser/extensions/extension_message_bubble.h"
|
| +#include "chrome/browser/extensions/extension_prefs.h"
|
| +#include "chrome/browser/extensions/extension_service.h"
|
| +#include "chrome/browser/ui/browser.h"
|
| +#include "chrome/browser/ui/browser_finder.h"
|
| +#include "chrome/common/url_constants.h"
|
| +#include "content/public/browser/user_metrics.h"
|
| +#include "grit/chromium_strings.h"
|
| +#include "grit/generated_resources.h"
|
| +#include "ui/base/l10n/l10n_util.h"
|
| +
|
| +namespace {
|
| +
|
| +// All the different titles we know about.
|
| +static const int kTitleIds[extensions::NUM_BUBBLE_TYPES] = {
|
| + IDS_EXTENSIONS_SUSPICIOUS_DISABLED_TITLE,
|
| + IDS_EXTENSIONS_DISABLE_DEVELOPER_MODE_TITLE,
|
| +};
|
| +
|
| +// All the different message bodies we know about. See also kBodyInjectIds.
|
| +static const int kBodyIds[extensions::NUM_BUBBLE_TYPES] = {
|
| + IDS_EXTENSIONS_SUSPICIOUS_DISABLED_BODY,
|
| + IDS_EXTENSIONS_DISABLE_DEVELOPER_MODE_BODY,
|
| +};
|
| +
|
| +// Sometimes we substitute a param in one of the kBodyIds, this specifies the
|
| +// value to use to replace the param. A 0 value means Accept no substitutes!
|
| +static const int kBodyInjectIds[extensions::NUM_BUBBLE_TYPES] = {
|
| + IDS_EXTENSION_WEB_STORE_TITLE,
|
| + 0,
|
| +};
|
| +
|
| +// All the labels we use for the Accept button. A 0 value means the bubble has
|
| +// no Accept button.
|
| +static const int kAcceptIds[extensions::NUM_BUBBLE_TYPES] = {
|
| + 0,
|
| + IDS_DISABLE,
|
| +};
|
| +
|
| +// All the labels we use for the Dismiss button.
|
| +static const int kDismissIds[extensions::NUM_BUBBLE_TYPES] = {
|
| + IDS_EXTENSIONS_SUSPICIOUS_DISABLED_BUTTON,
|
| + IDS_CANCEL,
|
| +};
|
| +
|
| +static const char* kLearnMoreLikeIds[extensions::NUM_BUBBLE_TYPES] = {
|
| + chrome::kRemoveNonCWSExtensionURL,
|
| + chrome::kChromeUIExtensionsURL,
|
| +};
|
| +
|
| +static const bool kShowExtensionList[extensions::NUM_BUBBLE_TYPES] = {
|
| + true,
|
| + false,
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +namespace extensions {
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// ExtensionMessageBubbleController
|
| +
|
| +ExtensionMessageBubbleController::ExtensionMessageBubbleController(
|
| + ExtensionListType type, Profile* profile)
|
| + : service_(extensions::ExtensionSystem::Get(profile)->extension_service()),
|
| + profile_(profile),
|
| + user_action_(ACTION_BOUNDARY),
|
| + type_(type),
|
| + has_notified_(false),
|
| + showing_bubble_(false) {
|
| +}
|
| +
|
| +ExtensionMessageBubbleController::~ExtensionMessageBubbleController() {
|
| +}
|
| +
|
| +bool ExtensionMessageBubbleController::HasExtensionList() {
|
| + if (has_notified_)
|
| + return false;
|
| +
|
| + scoped_ptr<const ExtensionSet> extension_set(
|
| + service_->GenerateInstalledExtensionsSet());
|
| + for (ExtensionSet::const_iterator it = extension_set->begin();
|
| + it != extension_set->end(); ++it) {
|
| + std::string id = (*it)->id();
|
| + if (!ShouldIncludeExtension(id))
|
| + continue;
|
| + extension_list_.push_back(id);
|
| + }
|
| +
|
| + // Log the UMA histogram.
|
| + switch (type_) {
|
| + case SUSPICIOUS_EXTENSIONS:
|
| + UMA_HISTOGRAM_COUNTS_100(
|
| + "ExtensionWipeoutBubble.ExtensionWipeoutCount",
|
| + extension_list_.size());
|
| + break;
|
| + case DEV_MODE_EXTENSIONS:
|
| + UMA_HISTOGRAM_COUNTS_100(
|
| + "DevModeExtensionBubble.ExtensionsInDevModeCount",
|
| + extension_list_.size());
|
| + break;
|
| + case NUM_BUBBLE_TYPES:
|
| + NOTREACHED();
|
| + break;
|
| + }
|
| +
|
| + has_notified_ = true;
|
| + return !extension_list_.empty();
|
| +}
|
| +
|
| +std::vector<string16>
|
| +ExtensionMessageBubbleController::GetExtensionList() const {
|
| + if (extension_list_.empty())
|
| + return std::vector<string16>();
|
| +
|
| + std::vector<string16> return_value;
|
| + for (ExtensionIdList::const_iterator it = extension_list_.begin();
|
| + it != extension_list_.end(); ++it) {
|
| + const Extension* extension = service_->GetInstalledExtension(*it);
|
| + if (extension) {
|
| + return_value.push_back(UTF8ToUTF16(extension->name()));
|
| + } else {
|
| + return_value.push_back(
|
| + ASCIIToUTF16(std::string("(unknown name) ") + *it));
|
| + // TODO(finnur): Add this as a string to the grd, for next milestone.
|
| + }
|
| + }
|
| + return return_value;
|
| +}
|
| +
|
| +void ExtensionMessageBubbleController::Show(ExtensionMessageBubble* bubble) {
|
| + // Wire up all the callbacks, to get notified what actions the user took.
|
| + base::Closure dismiss_button_callback =
|
| + base::Bind(&ExtensionMessageBubbleController::OnBubbleDismiss,
|
| + base::Unretained(this));
|
| + base::Closure action_button_callback =
|
| + base::Bind(&ExtensionMessageBubbleController::OnBubbleAction,
|
| + base::Unretained(this));
|
| + base::Closure link_callback =
|
| + base::Bind(&ExtensionMessageBubbleController::OnLinkClicked,
|
| + base::Unretained(this));
|
| + bubble->OnActionButtonClicked(action_button_callback);
|
| + bubble->OnDismissButtonClicked(dismiss_button_callback);
|
| + bubble->OnLinkClicked(link_callback);
|
| +
|
| + showing_bubble_ = true;
|
| + bubble->Show();
|
| +}
|
| +
|
| +string16 ExtensionMessageBubbleController::GetTitle() const {
|
| + return l10n_util::GetStringUTF16(kTitleIds[type_]);
|
| +}
|
| +
|
| +string16 ExtensionMessageBubbleController::GetMessageBody() const {
|
| + if (kBodyInjectIds[type_] == 0)
|
| + return l10n_util::GetStringUTF16(kBodyIds[type_]);
|
| +
|
| + return l10n_util::GetStringFUTF16(kBodyIds[type_],
|
| + l10n_util::GetStringUTF16(kBodyInjectIds[type_]));
|
| +}
|
| +
|
| +string16 ExtensionMessageBubbleController::GetOverflowText(
|
| + const string16& overflow_count) const {
|
| + return l10n_util::GetStringFUTF16(
|
| + IDS_EXTENSIONS_SUSPICIOUS_DISABLED_AND_N_MORE,
|
| + overflow_count);
|
| +}
|
| +
|
| +string16 ExtensionMessageBubbleController::GetLearnMoreLabel() const {
|
| + return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
|
| +}
|
| +
|
| +string16 ExtensionMessageBubbleController::GetActionButtonLabel() const {
|
| + if (!kAcceptIds[type_])
|
| + return string16();
|
| +
|
| + return l10n_util::GetStringUTF16(kAcceptIds[type_]);
|
| +}
|
| +
|
| +string16 ExtensionMessageBubbleController::GetDismissButtonLabel() const {
|
| + return l10n_util::GetStringUTF16(kDismissIds[type_]);
|
| +}
|
| +
|
| +bool ExtensionMessageBubbleController::ShouldShowExtensionList() const {
|
| + return kShowExtensionList[type_];
|
| +}
|
| +
|
| +void ExtensionMessageBubbleController::OnBubbleAction() {
|
| + DCHECK_EQ(ACTION_BOUNDARY, user_action_);
|
| + user_action_ = ACTION_EXECUTE;
|
| +
|
| + RecordAction(ACTION_EXECUTE);
|
| + PerformAction();
|
| + AcknowledgeExtensions();
|
| +}
|
| +
|
| +void ExtensionMessageBubbleController::OnBubbleDismiss() {
|
| + DCHECK_EQ(ACTION_BOUNDARY, user_action_);
|
| + user_action_ = ACTION_DISMISS;
|
| +
|
| + RecordAction(ACTION_DISMISS);
|
| + AcknowledgeExtensions();
|
| +}
|
| +
|
| +void ExtensionMessageBubbleController::OnLinkClicked() {
|
| + DCHECK_EQ(ACTION_BOUNDARY, user_action_);
|
| + user_action_ = ACTION_LEARN_MORE;
|
| +
|
| + RecordAction(ACTION_LEARN_MORE);
|
| + Browser* browser =
|
| + chrome::FindBrowserWithProfile(profile_, chrome::GetActiveDesktop());
|
| + if (browser) {
|
| + browser->OpenURL(
|
| + content::OpenURLParams(GURL(kLearnMoreLikeIds[type_]),
|
| + content::Referrer(),
|
| + NEW_FOREGROUND_TAB,
|
| + content::PAGE_TRANSITION_LINK,
|
| + false));
|
| + }
|
| + AcknowledgeExtensions();
|
| +}
|
| +
|
| +void ExtensionMessageBubbleController::AcknowledgeExtensions() {
|
| + for (ExtensionIdList::const_iterator it = extension_list_.begin();
|
| + it != extension_list_.end(); ++it)
|
| + AcknowledgeExtension(*it);
|
| + showing_bubble_ = false;
|
| +}
|
| +
|
| +void ExtensionMessageBubbleController::RecordAction(
|
| + UmaExtensionListHistogramOptions action) {
|
| + switch (type_) {
|
| + case SUSPICIOUS_EXTENSIONS:
|
| + UMA_HISTOGRAM_ENUMERATION("ExtensionWipeoutBubble.UserSelection",
|
| + action, ACTION_BOUNDARY);
|
| + break;
|
| + case DEV_MODE_EXTENSIONS:
|
| + UMA_HISTOGRAM_ENUMERATION("DevModeExtensionBubble.UserSelection",
|
| + action, ACTION_BOUNDARY);
|
| + break;
|
| + case NUM_BUBBLE_TYPES:
|
| + NOTREACHED();
|
| + break;
|
| + }
|
| +}
|
| +
|
| +} // namespace extensions
|
|
|