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.
5 #include "chrome/browser/notifications/notification_options_menu_model.h"
9 #include "base/logging.h"
10 #include "base/utf_string_conversions.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/extensions/extension_service.h"
13 #include "chrome/browser/notifications/balloon.h"
14 #include "chrome/browser/notifications/balloon_collection.h"
15 #include "chrome/browser/notifications/balloon_notification_ui_manager.h"
16 #include "chrome/browser/notifications/desktop_notification_service.h"
17 #include "chrome/browser/notifications/desktop_notification_service_factory.h"
18 #include "chrome/browser/notifications/notification.h"
19 #include "chrome/browser/notifications/notification_prefs_manager.h"
20 #include "chrome/browser/notifications/notification_ui_manager.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/ui/browser.h"
23 #include "chrome/browser/ui/browser_finder.h"
24 #include "chrome/browser/ui/chrome_pages.h"
25 #include "chrome/browser/ui/host_desktop.h"
26 #include "chrome/common/chrome_switches.h"
27 #include "chrome/common/content_settings_types.h"
28 #include "chrome/common/extensions/extension.h"
29 #include "chrome/common/url_constants.h"
30 #include "content/public/browser/web_contents_delegate.h"
31 #include "extensions/common/constants.h"
32 #include "grit/generated_resources.h"
33 #include "ui/base/l10n/l10n_util.h"
36 const int kTogglePermissionCommand
= 0;
37 const int kToggleExtensionCommand
= 1;
38 const int kOpenContentSettingsCommand
= 2;
39 const int kCornerSelectionSubMenu
= 3;
41 const int kCornerGroupId
= 10;
42 const int kCornerUpperLeft
= 11;
43 const int kCornerUpperRight
= 12;
44 const int kCornerLowerLeft
= 13;
45 const int kCornerLowerRight
= 14;
46 const int kCornerDefault
= 20;
48 CornerSelectionMenuModel::CornerSelectionMenuModel(Balloon
* balloon
)
49 : ALLOW_THIS_IN_INITIALIZER_LIST(ui::SimpleMenuModel(this)),
51 AddRadioItem(kCornerDefault
,
52 l10n_util::GetStringUTF16(IDS_NOTIFICATION_POSITION_DEFAULT
),
54 AddSeparator(ui::NORMAL_SEPARATOR
);
55 AddRadioItem(kCornerUpperLeft
,
56 l10n_util::GetStringUTF16(IDS_NOTIFICATION_POSITION_UPPER_LEFT
),
58 AddRadioItem(kCornerUpperRight
,
59 l10n_util::GetStringUTF16(IDS_NOTIFICATION_POSITION_UPPER_RIGHT
),
61 AddRadioItem(kCornerLowerLeft
,
62 l10n_util::GetStringUTF16(IDS_NOTIFICATION_POSITION_LOWER_LEFT
),
64 AddRadioItem(kCornerLowerRight
,
65 l10n_util::GetStringUTF16(IDS_NOTIFICATION_POSITION_LOWER_RIGHT
),
69 CornerSelectionMenuModel::~CornerSelectionMenuModel() {
72 bool CornerSelectionMenuModel::IsCommandIdChecked(int command_id
) const {
73 // TODO(dimich): MessageCenter does not use this preference (yet?)
74 if (NotificationUIManager::DelegatesToMessageCenter())
77 NotificationPrefsManager
* prefs
=
78 static_cast<BalloonNotificationUIManager
*>(
79 g_browser_process
->notification_ui_manager())->prefs_manager();
81 BalloonCollection::PositionPreference current
=
82 prefs
->GetPositionPreference();
84 if (command_id
== kCornerUpperLeft
)
85 return (current
== BalloonCollection::UPPER_LEFT
);
86 else if (command_id
== kCornerUpperRight
)
87 return (current
== BalloonCollection::UPPER_RIGHT
);
88 else if (command_id
== kCornerLowerLeft
)
89 return (current
== BalloonCollection::LOWER_LEFT
);
90 else if (command_id
== kCornerLowerRight
)
91 return (current
== BalloonCollection::LOWER_RIGHT
);
92 else if (command_id
== kCornerDefault
)
93 return (current
== BalloonCollection::DEFAULT_POSITION
);
99 bool CornerSelectionMenuModel::IsCommandIdEnabled(int command_id
) const {
100 // All the menu options are always enabled.
104 bool CornerSelectionMenuModel::GetAcceleratorForCommandId(
105 int command_id
, ui::Accelerator
* accelerator
) {
106 // Currently no accelerators.
110 void CornerSelectionMenuModel::ExecuteCommand(int command_id
, int event_flags
) {
111 // TODO(dimich): MessageCenter does not use this preference (yet?)
112 if (NotificationUIManager::DelegatesToMessageCenter())
115 NotificationPrefsManager
* prefs
=
116 static_cast<BalloonNotificationUIManager
*>(
117 g_browser_process
->notification_ui_manager())->prefs_manager();
119 if (command_id
== kCornerUpperLeft
)
120 prefs
->SetPositionPreference(BalloonCollection::UPPER_LEFT
);
121 else if (command_id
== kCornerUpperRight
)
122 prefs
->SetPositionPreference(BalloonCollection::UPPER_RIGHT
);
123 else if (command_id
== kCornerLowerLeft
)
124 prefs
->SetPositionPreference(BalloonCollection::LOWER_LEFT
);
125 else if (command_id
== kCornerLowerRight
)
126 prefs
->SetPositionPreference(BalloonCollection::LOWER_RIGHT
);
127 else if (command_id
== kCornerDefault
)
128 prefs
->SetPositionPreference(BalloonCollection::DEFAULT_POSITION
);
133 NotificationOptionsMenuModel::NotificationOptionsMenuModel(Balloon
* balloon
)
134 : ALLOW_THIS_IN_INITIALIZER_LIST(ui::SimpleMenuModel(this)),
136 const Notification
& notification
= balloon
->notification();
137 const GURL
& origin
= notification
.origin_url();
139 if (origin
.SchemeIs(extensions::kExtensionScheme
)) {
140 ExtensionService
* extension_service
=
141 balloon_
->profile()->GetExtensionService();
142 const extensions::Extension
* extension
=
143 extension_service
->extensions()->GetExtensionOrAppByURL(
144 ExtensionURLInfo(origin
));
145 // We get back no extension here when we show the notification after
146 // the extension has crashed.
148 const string16 disable_label
= l10n_util::GetStringUTF16(
149 IDS_EXTENSIONS_DISABLE
);
150 AddItem(kToggleExtensionCommand
, disable_label
);
152 } else if (!notification
.display_source().empty()) {
153 const string16 disable_label
= l10n_util::GetStringFUTF16(
154 IDS_NOTIFICATION_BALLOON_REVOKE_MESSAGE
,
155 notification
.display_source());
156 AddItem(kTogglePermissionCommand
, disable_label
);
159 if (!notification
.display_source().empty()) {
160 const string16 settings_label
= l10n_util::GetStringUTF16(
161 IDS_NOTIFICATIONS_SETTINGS_BUTTON
);
162 AddItem(kOpenContentSettingsCommand
, settings_label
);
165 corner_menu_model_
.reset(new CornerSelectionMenuModel(balloon
));
166 AddSubMenu(kCornerSelectionSubMenu
,
167 l10n_util::GetStringUTF16(IDS_NOTIFICATION_CHOOSE_POSITION
),
168 corner_menu_model_
.get());
171 NotificationOptionsMenuModel::~NotificationOptionsMenuModel() {
174 bool NotificationOptionsMenuModel::IsItemForCommandIdDynamic(int command_id
)
176 return command_id
== kTogglePermissionCommand
||
177 command_id
== kToggleExtensionCommand
;
180 string16
NotificationOptionsMenuModel::GetLabelForCommandId(int command_id
)
182 // TODO(tfarina,johnnyg): Remove this code if we decide to close notifications
183 // after permissions are revoked.
184 if (command_id
== kTogglePermissionCommand
||
185 command_id
== kToggleExtensionCommand
) {
186 const Notification
& notification
= balloon_
->notification();
187 const GURL
& origin
= notification
.origin_url();
189 DesktopNotificationService
* service
=
190 DesktopNotificationServiceFactory::GetForProfile(balloon_
->profile());
191 if (origin
.SchemeIs(extensions::kExtensionScheme
)) {
192 ExtensionService
* extension_service
=
193 balloon_
->profile()->GetExtensionService();
194 const extensions::Extension
* extension
=
195 extension_service
->extensions()->GetExtensionOrAppByURL(
196 ExtensionURLInfo(origin
));
198 return l10n_util::GetStringUTF16(
199 extension_service
->IsExtensionEnabled(extension
->id()) ?
200 IDS_EXTENSIONS_DISABLE
:
201 IDS_EXTENSIONS_ENABLE
);
204 if (service
->GetContentSetting(origin
) == CONTENT_SETTING_ALLOW
) {
205 return l10n_util::GetStringFUTF16(
206 IDS_NOTIFICATION_BALLOON_REVOKE_MESSAGE
,
207 notification
.display_source());
209 return l10n_util::GetStringFUTF16(
210 IDS_NOTIFICATION_BALLOON_ENABLE_MESSAGE
,
211 notification
.display_source());
214 } else if (command_id
== kOpenContentSettingsCommand
) {
215 return l10n_util::GetStringUTF16(IDS_NOTIFICATIONS_SETTINGS_BUTTON
);
220 bool NotificationOptionsMenuModel::IsCommandIdChecked(int /* command_id */)
222 // Nothing in the menu is checked.
226 bool NotificationOptionsMenuModel::IsCommandIdEnabled(int /* command_id */)
228 // All the menu options are always enabled.
232 bool NotificationOptionsMenuModel::GetAcceleratorForCommandId(
233 int /* command_id */, ui::Accelerator
* /* accelerator */) {
234 // Currently no accelerators.
238 void NotificationOptionsMenuModel::ExecuteCommand(int command_id
,
240 DesktopNotificationService
* service
=
241 DesktopNotificationServiceFactory::GetForProfile(balloon_
->profile());
242 ExtensionService
* extension_service
=
243 balloon_
->profile()->GetExtensionService();
244 const GURL
& origin
= balloon_
->notification().origin_url();
245 switch (command_id
) {
246 case kTogglePermissionCommand
:
247 if (service
->GetContentSetting(origin
) == CONTENT_SETTING_ALLOW
)
248 service
->DenyPermission(origin
);
250 service
->GrantPermission(origin
);
252 case kToggleExtensionCommand
: {
253 const extensions::Extension
* extension
=
254 extension_service
->extensions()->GetExtensionOrAppByURL(
255 ExtensionURLInfo(origin
));
257 const std::string
& id
= extension
->id();
258 if (extension_service
->IsExtensionEnabled(id
))
259 extension_service
->DisableExtension(
260 id
, extensions::Extension::DISABLE_USER_ACTION
);
262 extension_service
->EnableExtension(id
);
266 case kOpenContentSettingsCommand
: {
267 chrome::HostDesktopType active_desktop
= chrome::GetActiveDesktop();
268 Browser
* browser
= chrome::FindLastActiveWithProfile(
269 balloon_
->profile(), active_desktop
);
271 // It is possible that there is no browser window (e.g. when there are
272 // background pages, or for a chrome frame process on windows).
273 browser
= new Browser(Browser::CreateParams(balloon_
->profile(),
276 chrome::ShowContentSettings(browser
, CONTENT_SETTINGS_TYPE_NOTIFICATIONS
);