Home | History | Annotate | Download | only in notifications
      1 // Copyright (c) 2011 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/notifications/notification_options_menu_model.h"
      6 
      7 #include "base/compiler_specific.h"
      8 #include "base/logging.h"
      9 #include "base/utf_string_conversions.h"
     10 #include "chrome/browser/browser_process.h"
     11 #include "chrome/browser/extensions/extension_service.h"
     12 #include "chrome/browser/notifications/balloon_collection.h"
     13 #include "chrome/browser/notifications/desktop_notification_service.h"
     14 #include "chrome/browser/notifications/desktop_notification_service_factory.h"
     15 #include "chrome/browser/notifications/notification.h"
     16 #include "chrome/browser/notifications/notification_ui_manager.h"
     17 #include "chrome/browser/notifications/notifications_prefs_cache.h"
     18 #include "chrome/browser/profiles/profile.h"
     19 #include "chrome/browser/ui/browser_list.h"
     20 #include "chrome/common/chrome_switches.h"
     21 #include "chrome/common/content_settings_types.h"
     22 #include "chrome/common/extensions/extension.h"
     23 #include "chrome/common/url_constants.h"
     24 #include "content/browser/tab_contents/tab_contents_delegate.h"
     25 #include "grit/generated_resources.h"
     26 #include "ui/base/l10n/l10n_util.h"
     27 
     28 // Menu commands
     29 const int kTogglePermissionCommand = 0;
     30 const int kToggleExtensionCommand = 1;
     31 const int kOpenContentSettingsCommand = 2;
     32 const int kCornerSelectionSubMenu = 3;
     33 
     34 const int kCornerGroupId = 10;
     35 const int kCornerUpperLeft = 11;
     36 const int kCornerUpperRight = 12;
     37 const int kCornerLowerLeft = 13;
     38 const int kCornerLowerRight = 14;
     39 const int kCornerDefault = 20;
     40 
     41 CornerSelectionMenuModel::CornerSelectionMenuModel(Balloon* balloon)
     42     : ALLOW_THIS_IN_INITIALIZER_LIST(ui::SimpleMenuModel(this)),
     43       balloon_(balloon) {
     44   AddRadioItem(kCornerDefault,
     45                l10n_util::GetStringUTF16(IDS_NOTIFICATION_POSITION_DEFAULT),
     46                kCornerGroupId);
     47   AddSeparator();
     48   AddRadioItem(kCornerUpperLeft,
     49                l10n_util::GetStringUTF16(IDS_NOTIFICATION_POSITION_UPPER_LEFT),
     50                kCornerGroupId);
     51   AddRadioItem(kCornerUpperRight,
     52                l10n_util::GetStringUTF16(IDS_NOTIFICATION_POSITION_UPPER_RIGHT),
     53                kCornerGroupId);
     54   AddRadioItem(kCornerLowerLeft,
     55                l10n_util::GetStringUTF16(IDS_NOTIFICATION_POSITION_LOWER_LEFT),
     56                kCornerGroupId);
     57   AddRadioItem(kCornerLowerRight,
     58                l10n_util::GetStringUTF16(IDS_NOTIFICATION_POSITION_LOWER_RIGHT),
     59                kCornerGroupId);
     60 }
     61 
     62 CornerSelectionMenuModel::~CornerSelectionMenuModel() {
     63 }
     64 
     65 bool CornerSelectionMenuModel::IsCommandIdChecked(int command_id) const {
     66   NotificationUIManager* ui = g_browser_process->notification_ui_manager();
     67   BalloonCollection::PositionPreference current = ui->GetPositionPreference();
     68 
     69   if (command_id == kCornerUpperLeft)
     70     return (current == BalloonCollection::UPPER_LEFT);
     71   else if (command_id == kCornerUpperRight)
     72     return (current == BalloonCollection::UPPER_RIGHT);
     73   else if (command_id == kCornerLowerLeft)
     74     return (current == BalloonCollection::LOWER_LEFT);
     75   else if (command_id == kCornerLowerRight)
     76     return (current == BalloonCollection::LOWER_RIGHT);
     77   else if (command_id == kCornerDefault)
     78     return (current == BalloonCollection::DEFAULT_POSITION);
     79 
     80   NOTREACHED();
     81   return false;
     82 }
     83 
     84 bool CornerSelectionMenuModel::IsCommandIdEnabled(int command_id) const {
     85   // All the menu options are always enabled.
     86   return true;
     87 }
     88 
     89 bool CornerSelectionMenuModel::GetAcceleratorForCommandId(
     90     int command_id, ui::Accelerator* accelerator) {
     91   // Currently no accelerators.
     92   return false;
     93 }
     94 
     95 void CornerSelectionMenuModel::ExecuteCommand(int command_id) {
     96   NotificationUIManager* ui = g_browser_process->notification_ui_manager();
     97 
     98   if (command_id == kCornerUpperLeft)
     99     ui->SetPositionPreference(BalloonCollection::UPPER_LEFT);
    100   else if (command_id == kCornerUpperRight)
    101     ui->SetPositionPreference(BalloonCollection::UPPER_RIGHT);
    102   else if (command_id == kCornerLowerLeft)
    103     ui->SetPositionPreference(BalloonCollection::LOWER_LEFT);
    104   else if (command_id == kCornerLowerRight)
    105     ui->SetPositionPreference(BalloonCollection::LOWER_RIGHT);
    106   else if (command_id == kCornerDefault)
    107     ui->SetPositionPreference(BalloonCollection::DEFAULT_POSITION);
    108   else
    109     NOTREACHED();
    110 }
    111 
    112 NotificationOptionsMenuModel::NotificationOptionsMenuModel(Balloon* balloon)
    113     : ALLOW_THIS_IN_INITIALIZER_LIST(ui::SimpleMenuModel(this)),
    114       balloon_(balloon) {
    115   const Notification& notification = balloon->notification();
    116   const GURL& origin = notification.origin_url();
    117 
    118   if (origin.SchemeIs(chrome::kExtensionScheme)) {
    119     ExtensionService* ext_service =
    120         balloon_->profile()->GetExtensionService();
    121     const Extension* extension = ext_service->GetExtensionByURL(origin);
    122     // We get back no extension here when we show the notification after
    123     // the extension has crashed.
    124     if (extension) {
    125       const string16 disable_label = l10n_util::GetStringUTF16(
    126           IDS_EXTENSIONS_DISABLE);
    127       AddItem(kToggleExtensionCommand, disable_label);
    128     }
    129   } else {
    130     const string16 disable_label = l10n_util::GetStringFUTF16(
    131         IDS_NOTIFICATION_BALLOON_REVOKE_MESSAGE,
    132         notification.display_source());
    133     AddItem(kTogglePermissionCommand, disable_label);
    134   }
    135 
    136   const string16 settings_label = l10n_util::GetStringUTF16(
    137       IDS_NOTIFICATIONS_SETTINGS_BUTTON);
    138   AddItem(kOpenContentSettingsCommand, settings_label);
    139 
    140   corner_menu_model_.reset(new CornerSelectionMenuModel(balloon));
    141   AddSubMenu(kCornerSelectionSubMenu,
    142              l10n_util::GetStringUTF16(IDS_NOTIFICATION_CHOOSE_POSITION),
    143              corner_menu_model_.get());
    144 }
    145 
    146 NotificationOptionsMenuModel::~NotificationOptionsMenuModel() {
    147 }
    148 
    149 bool NotificationOptionsMenuModel::IsItemForCommandIdDynamic(int command_id)
    150     const {
    151   return command_id == kTogglePermissionCommand ||
    152          command_id == kToggleExtensionCommand;
    153 }
    154 
    155 string16 NotificationOptionsMenuModel::GetLabelForCommandId(int command_id)
    156     const {
    157   // TODO(tfarina,johnnyg): Remove this code if we decide to close notifications
    158   // after permissions are revoked.
    159   if (command_id == kTogglePermissionCommand ||
    160       command_id == kToggleExtensionCommand) {
    161     const Notification& notification = balloon_->notification();
    162     const GURL& origin = notification.origin_url();
    163 
    164     DesktopNotificationService* service =
    165         DesktopNotificationServiceFactory::GetForProfile(balloon_->profile());
    166     if (origin.SchemeIs(chrome::kExtensionScheme)) {
    167       ExtensionService* ext_service =
    168           balloon_->profile()->GetExtensionService();
    169       const Extension* extension = ext_service->GetExtensionByURL(origin);
    170       if (extension) {
    171         ExtensionPrefs* extension_prefs = ext_service->extension_prefs();
    172         const std::string& id = extension->id();
    173         if (extension_prefs->GetExtensionState(id) == Extension::ENABLED)
    174           return l10n_util::GetStringUTF16(IDS_EXTENSIONS_DISABLE);
    175         else
    176           return l10n_util::GetStringUTF16(IDS_EXTENSIONS_ENABLE);
    177       }
    178     } else {
    179       if (service->GetContentSetting(origin) == CONTENT_SETTING_ALLOW) {
    180         return l10n_util::GetStringFUTF16(
    181             IDS_NOTIFICATION_BALLOON_REVOKE_MESSAGE,
    182             notification.display_source());
    183       } else {
    184         return l10n_util::GetStringFUTF16(
    185             IDS_NOTIFICATION_BALLOON_ENABLE_MESSAGE,
    186             notification.display_source());
    187       }
    188     }
    189   } else if (command_id == kOpenContentSettingsCommand) {
    190     return l10n_util::GetStringUTF16(IDS_NOTIFICATIONS_SETTINGS_BUTTON);
    191   }
    192   return string16();
    193 }
    194 
    195 bool NotificationOptionsMenuModel::IsCommandIdChecked(int /* command_id */)
    196     const {
    197   // Nothing in the menu is checked.
    198   return false;
    199 }
    200 
    201 bool NotificationOptionsMenuModel::IsCommandIdEnabled(int /* command_id */)
    202     const {
    203   // All the menu options are always enabled.
    204   return true;
    205 }
    206 
    207 bool NotificationOptionsMenuModel::GetAcceleratorForCommandId(
    208     int /* command_id */, ui::Accelerator* /* accelerator */) {
    209   // Currently no accelerators.
    210   return false;
    211 }
    212 
    213 void NotificationOptionsMenuModel::ExecuteCommand(int command_id) {
    214   DesktopNotificationService* service =
    215       DesktopNotificationServiceFactory::GetForProfile(balloon_->profile());
    216   ExtensionService* ext_service =
    217       balloon_->profile()->GetExtensionService();
    218   const GURL& origin = balloon_->notification().origin_url();
    219   switch (command_id) {
    220     case kTogglePermissionCommand:
    221       if (service->GetContentSetting(origin) == CONTENT_SETTING_ALLOW)
    222         service->DenyPermission(origin);
    223       else
    224         service->GrantPermission(origin);
    225       break;
    226     case kToggleExtensionCommand: {
    227       const Extension* extension = ext_service->GetExtensionByURL(origin);
    228       if (extension) {
    229         ExtensionPrefs* extension_prefs = ext_service->extension_prefs();
    230         const std::string& id = extension->id();
    231         if (extension_prefs->GetExtensionState(id) == Extension::ENABLED)
    232           ext_service->DisableExtension(id);
    233         else
    234           ext_service->EnableExtension(id);
    235       }
    236       break;
    237     }
    238     case kOpenContentSettingsCommand: {
    239       Browser* browser =
    240           BrowserList::GetLastActiveWithProfile(balloon_->profile());
    241       if (!browser) {
    242         // It is possible that there is no browser window (e.g. when there are
    243         // background pages, or for a chrome frame process on windows).
    244         browser = Browser::Create(balloon_->profile());
    245       }
    246       static_cast<TabContentsDelegate*>(browser)->ShowContentSettingsPage(
    247           CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
    248       break;
    249     }
    250     default:
    251       NOTREACHED();
    252       break;
    253   }
    254 }
    255