Home | History | Annotate | Download | only in extensions
      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/extension_message_bubble_controller.h"
      6 
      7 #include "base/bind.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_prefs.h"
     12 #include "chrome/browser/extensions/extension_service.h"
     13 #include "chrome/browser/ui/browser.h"
     14 #include "chrome/browser/ui/browser_finder.h"
     15 #include "chrome/common/url_constants.h"
     16 #include "content/public/browser/user_metrics.h"
     17 #include "grit/chromium_strings.h"
     18 #include "grit/generated_resources.h"
     19 #include "ui/base/l10n/l10n_util.h"
     20 
     21 namespace extensions {
     22 
     23 ////////////////////////////////////////////////////////////////////////////////
     24 // ExtensionMessageBubbleController
     25 
     26 ExtensionMessageBubbleController::ExtensionMessageBubbleController(
     27     Delegate* delegate, Profile* profile)
     28     : service_(extensions::ExtensionSystem::Get(profile)->extension_service()),
     29       profile_(profile),
     30       user_action_(ACTION_BOUNDARY),
     31       delegate_(delegate),
     32       initialized_(false),
     33       has_notified_(false) {
     34 }
     35 
     36 ExtensionMessageBubbleController::~ExtensionMessageBubbleController() {
     37 }
     38 
     39 bool ExtensionMessageBubbleController::ShouldShow() {
     40   if (has_notified_)
     41     return false;
     42 
     43   has_notified_ = true;
     44   return !GetOrCreateExtensionList()->empty();
     45 }
     46 
     47 std::vector<string16>
     48 ExtensionMessageBubbleController::GetExtensionList() {
     49   ExtensionIdList* list = GetOrCreateExtensionList();
     50   if (list->empty())
     51     return std::vector<string16>();
     52 
     53   std::vector<string16> return_value;
     54   for (ExtensionIdList::const_iterator it = list->begin();
     55        it != list->end(); ++it) {
     56     const Extension* extension = service_->GetInstalledExtension(*it);
     57     if (extension) {
     58       return_value.push_back(UTF8ToUTF16(extension->name()));
     59     } else {
     60       return_value.push_back(
     61           ASCIIToUTF16(std::string("(unknown name) ") + *it));
     62       // TODO(finnur): Add this as a string to the grd, for next milestone.
     63     }
     64   }
     65   return return_value;
     66 }
     67 
     68 const ExtensionIdList& ExtensionMessageBubbleController::GetExtensionIdList() {
     69   return *GetOrCreateExtensionList();
     70 }
     71 
     72 void ExtensionMessageBubbleController::Show(ExtensionMessageBubble* bubble) {
     73   // Wire up all the callbacks, to get notified what actions the user took.
     74   base::Closure dismiss_button_callback =
     75       base::Bind(&ExtensionMessageBubbleController::OnBubbleDismiss,
     76       base::Unretained(this));
     77   base::Closure action_button_callback =
     78       base::Bind(&ExtensionMessageBubbleController::OnBubbleAction,
     79       base::Unretained(this));
     80   base::Closure link_callback =
     81       base::Bind(&ExtensionMessageBubbleController::OnLinkClicked,
     82       base::Unretained(this));
     83   bubble->OnActionButtonClicked(action_button_callback);
     84   bubble->OnDismissButtonClicked(dismiss_button_callback);
     85   bubble->OnLinkClicked(link_callback);
     86 
     87   bubble->Show();
     88 }
     89 
     90 void ExtensionMessageBubbleController::OnBubbleAction() {
     91   DCHECK_EQ(ACTION_BOUNDARY, user_action_);
     92   user_action_ = ACTION_EXECUTE;
     93 
     94   delegate_->LogAction(ACTION_EXECUTE);
     95   delegate_->PerformAction(*GetOrCreateExtensionList());
     96   AcknowledgeExtensions();
     97 }
     98 
     99 void ExtensionMessageBubbleController::OnBubbleDismiss() {
    100   DCHECK_EQ(ACTION_BOUNDARY, user_action_);
    101   user_action_ = ACTION_DISMISS;
    102 
    103   delegate_->LogAction(ACTION_DISMISS);
    104   AcknowledgeExtensions();
    105 }
    106 
    107 void ExtensionMessageBubbleController::OnLinkClicked() {
    108   DCHECK_EQ(ACTION_BOUNDARY, user_action_);
    109   user_action_ = ACTION_LEARN_MORE;
    110 
    111   delegate_->LogAction(ACTION_LEARN_MORE);
    112   Browser* browser =
    113       chrome::FindBrowserWithProfile(profile_, chrome::GetActiveDesktop());
    114   if (browser) {
    115     browser->OpenURL(
    116         content::OpenURLParams(delegate_->GetLearnMoreUrl(),
    117                                content::Referrer(),
    118                                NEW_FOREGROUND_TAB,
    119                                content::PAGE_TRANSITION_LINK,
    120                                false));
    121   }
    122   AcknowledgeExtensions();
    123 }
    124 
    125 void ExtensionMessageBubbleController::AcknowledgeExtensions() {
    126   ExtensionIdList* list = GetOrCreateExtensionList();
    127   for (ExtensionIdList::const_iterator it = list->begin();
    128        it != list->end(); ++it)
    129     delegate_->AcknowledgeExtension(*it, user_action_);
    130 }
    131 
    132 ExtensionIdList* ExtensionMessageBubbleController::GetOrCreateExtensionList() {
    133   if (!service_)
    134     return &extension_list_;  // Can occur during testing.
    135 
    136   if (!initialized_) {
    137     scoped_ptr<const ExtensionSet> extension_set(
    138         service_->GenerateInstalledExtensionsSet());
    139     for (ExtensionSet::const_iterator it = extension_set->begin();
    140          it != extension_set->end(); ++it) {
    141       std::string id = (*it)->id();
    142       if (!delegate_->ShouldIncludeExtension(id))
    143         continue;
    144       extension_list_.push_back(id);
    145     }
    146 
    147     delegate_->LogExtensionCount(extension_list_.size());
    148     initialized_ = true;
    149   }
    150 
    151   return &extension_list_;
    152 }
    153 
    154 }  // namespace extensions
    155