• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
CornerSelectionMenuModel(Balloon * balloon)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 
~CornerSelectionMenuModel()62 CornerSelectionMenuModel::~CornerSelectionMenuModel() {
63 }
64 
IsCommandIdChecked(int command_id) const65 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 
IsCommandIdEnabled(int command_id) const84 bool CornerSelectionMenuModel::IsCommandIdEnabled(int command_id) const {
85   // All the menu options are always enabled.
86   return true;
87 }
88 
GetAcceleratorForCommandId(int command_id,ui::Accelerator * accelerator)89 bool CornerSelectionMenuModel::GetAcceleratorForCommandId(
90     int command_id, ui::Accelerator* accelerator) {
91   // Currently no accelerators.
92   return false;
93 }
94 
ExecuteCommand(int command_id)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 
NotificationOptionsMenuModel(Balloon * balloon)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 
~NotificationOptionsMenuModel()146 NotificationOptionsMenuModel::~NotificationOptionsMenuModel() {
147 }
148 
IsItemForCommandIdDynamic(int command_id) const149 bool NotificationOptionsMenuModel::IsItemForCommandIdDynamic(int command_id)
150     const {
151   return command_id == kTogglePermissionCommand ||
152          command_id == kToggleExtensionCommand;
153 }
154 
GetLabelForCommandId(int command_id) const155 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 
IsCommandIdChecked(int) const195 bool NotificationOptionsMenuModel::IsCommandIdChecked(int /* command_id */)
196     const {
197   // Nothing in the menu is checked.
198   return false;
199 }
200 
IsCommandIdEnabled(int) const201 bool NotificationOptionsMenuModel::IsCommandIdEnabled(int /* command_id */)
202     const {
203   // All the menu options are always enabled.
204   return true;
205 }
206 
GetAcceleratorForCommandId(int,ui::Accelerator *)207 bool NotificationOptionsMenuModel::GetAcceleratorForCommandId(
208     int /* command_id */, ui::Accelerator* /* accelerator */) {
209   // Currently no accelerators.
210   return false;
211 }
212 
ExecuteCommand(int command_id)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