Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2012 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/theme_installed_infobar_delegate.h"
      6 
      7 #include <string>
      8 
      9 #include "base/strings/utf_string_conversions.h"
     10 #include "chrome/browser/chrome_notification_types.h"
     11 #include "chrome/browser/extensions/extension_service.h"
     12 #include "chrome/browser/infobars/infobar_service.h"
     13 #include "chrome/browser/profiles/profile.h"
     14 #include "chrome/browser/themes/theme_service.h"
     15 #include "chrome/browser/themes/theme_service_factory.h"
     16 #include "chrome/browser/ui/browser_finder.h"
     17 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     18 #include "chrome/common/extensions/extension.h"
     19 #include "content/public/browser/notification_source.h"
     20 #include "grit/generated_resources.h"
     21 #include "grit/theme_resources.h"
     22 #include "ui/base/l10n/l10n_util.h"
     23 
     24 
     25 // static
     26 void ThemeInstalledInfoBarDelegate::Create(
     27     const extensions::Extension* new_theme,
     28     Profile* profile,
     29     const std::string& previous_theme_id,
     30     bool previous_using_native_theme) {
     31   DCHECK(new_theme);
     32   if (!new_theme->is_theme())
     33     return;
     34 
     35   // Create the new infobar.
     36   // FindTabbedBrowser() is called with |match_original_profiles| true because a
     37   // theme install in either a normal or incognito window for a profile affects
     38   // all normal and incognito windows for that profile.
     39   Browser* browser =
     40       chrome::FindTabbedBrowser(profile, true, chrome::GetActiveDesktop());
     41   if (!browser)
     42     return;
     43   content::WebContents* web_contents =
     44       browser->tab_strip_model()->GetActiveWebContents();
     45   if (!web_contents)
     46     return;
     47   InfoBarService* infobar_service =
     48       InfoBarService::FromWebContents(web_contents);
     49   ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile);
     50   scoped_ptr<InfoBarDelegate> new_infobar(new ThemeInstalledInfoBarDelegate(
     51       infobar_service, profile->GetExtensionService(), theme_service, new_theme,
     52       previous_theme_id, previous_using_native_theme));
     53 
     54   // If there's a previous theme infobar, just replace that instead of adding a
     55   // new one.
     56   for (size_t i = 0; i < infobar_service->infobar_count(); ++i) {
     57     InfoBarDelegate* old_infobar = infobar_service->infobar_at(i);
     58     ThemeInstalledInfoBarDelegate* theme_infobar =
     59         old_infobar->AsThemePreviewInfobarDelegate();
     60     if (theme_infobar) {
     61       // If the user installed the same theme twice, ignore the second install
     62       // and keep the first install info bar, so that they can easily undo to
     63       // get back the previous theme.
     64       if (theme_infobar->theme_id_ != new_theme->id()) {
     65         infobar_service->ReplaceInfoBar(old_infobar, new_infobar.Pass());
     66         theme_service->OnInfobarDisplayed();
     67       }
     68       return;
     69     }
     70   }
     71 
     72   // No previous theme infobar, so add this.
     73   infobar_service->AddInfoBar(new_infobar.Pass());
     74   theme_service->OnInfobarDisplayed();
     75 }
     76 
     77 ThemeInstalledInfoBarDelegate::ThemeInstalledInfoBarDelegate(
     78     InfoBarService* infobar_service,
     79     ExtensionService* extension_service,
     80     ThemeService* theme_service,
     81     const extensions::Extension* new_theme,
     82     const std::string& previous_theme_id,
     83     bool previous_using_native_theme)
     84     : ConfirmInfoBarDelegate(infobar_service),
     85       extension_service_(extension_service),
     86       theme_service_(theme_service),
     87       name_(new_theme->name()),
     88       theme_id_(new_theme->id()),
     89       previous_theme_id_(previous_theme_id),
     90       previous_using_native_theme_(previous_using_native_theme) {
     91   registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED,
     92                  content::Source<ThemeService>(theme_service_));
     93 }
     94 
     95 ThemeInstalledInfoBarDelegate::~ThemeInstalledInfoBarDelegate() {
     96   // We don't want any notifications while we're running our destructor.
     97   registrar_.RemoveAll();
     98 
     99   theme_service_->OnInfobarDestroyed();
    100 }
    101 
    102 int ThemeInstalledInfoBarDelegate::GetIconID() const {
    103   // TODO(aa): Reply with the theme's icon, but this requires reading it
    104   // asynchronously from disk.
    105   return IDR_INFOBAR_THEME;
    106 }
    107 
    108 InfoBarDelegate::Type ThemeInstalledInfoBarDelegate::GetInfoBarType() const {
    109   return PAGE_ACTION_TYPE;
    110 }
    111 
    112 ThemeInstalledInfoBarDelegate*
    113     ThemeInstalledInfoBarDelegate::AsThemePreviewInfobarDelegate() {
    114   return this;
    115 }
    116 
    117 string16 ThemeInstalledInfoBarDelegate::GetMessageText() const {
    118   return l10n_util::GetStringFUTF16(IDS_THEME_INSTALL_INFOBAR_LABEL,
    119                                     UTF8ToUTF16(name_));
    120 }
    121 
    122 int ThemeInstalledInfoBarDelegate::GetButtons() const {
    123   return BUTTON_CANCEL;
    124 }
    125 
    126 string16 ThemeInstalledInfoBarDelegate::GetButtonLabel(
    127     InfoBarButton button) const {
    128   DCHECK_EQ(BUTTON_CANCEL, button);
    129   return l10n_util::GetStringUTF16(IDS_THEME_INSTALL_INFOBAR_UNDO_BUTTON);
    130 }
    131 
    132 bool ThemeInstalledInfoBarDelegate::Cancel() {
    133   if (!previous_theme_id_.empty()) {
    134     const extensions::Extension* previous_theme =
    135         extension_service_->GetExtensionById(previous_theme_id_, true);
    136     if (previous_theme) {
    137       theme_service_->SetTheme(previous_theme);
    138       return false;  // The theme change will close us.
    139     }
    140   }
    141 
    142   if (previous_using_native_theme_)
    143     theme_service_->SetNativeTheme();
    144   else
    145     theme_service_->UseDefaultTheme();
    146   return false;  // The theme change will close us.
    147 }
    148 
    149 void ThemeInstalledInfoBarDelegate::Observe(
    150     int type,
    151     const content::NotificationSource& source,
    152     const content::NotificationDetails& details) {
    153   DCHECK_EQ(chrome::NOTIFICATION_BROWSER_THEME_CHANGED, type);
    154   // If the new theme is different from what this info bar is associated with,
    155   // close this info bar since it is no longer relevant.
    156   if (theme_id_ != theme_service_->GetThemeID())
    157     RemoveSelf();
    158 }
    159