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/strings/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/url_constants.h"
29 #include "content/public/browser/web_contents_delegate.h"
30 #include "extensions/common/constants.h"
31 #include "extensions/common/extension.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 : 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 : 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(origin
);
144 // We get back no extension here when we show the notification after
145 // the extension has crashed.
147 const base::string16 disable_label
= l10n_util::GetStringUTF16(
148 IDS_EXTENSIONS_DISABLE
);
149 AddItem(kToggleExtensionCommand
, disable_label
);
151 } else if (!notification
.display_source().empty()) {
152 const base::string16 disable_label
= l10n_util::GetStringFUTF16(
153 IDS_NOTIFICATION_BALLOON_REVOKE_MESSAGE
,
154 notification
.display_source());
155 AddItem(kTogglePermissionCommand
, disable_label
);
158 if (!notification
.display_source().empty()) {
159 const base::string16 settings_label
= l10n_util::GetStringUTF16(
160 IDS_NOTIFICATIONS_SETTINGS_BUTTON
);
161 AddItem(kOpenContentSettingsCommand
, settings_label
);
164 corner_menu_model_
.reset(new CornerSelectionMenuModel(balloon
));
165 AddSubMenu(kCornerSelectionSubMenu
,
166 l10n_util::GetStringUTF16(IDS_NOTIFICATION_CHOOSE_POSITION
),
167 corner_menu_model_
.get());
170 NotificationOptionsMenuModel::~NotificationOptionsMenuModel() {
173 bool NotificationOptionsMenuModel::IsItemForCommandIdDynamic(int command_id
)
175 return command_id
== kTogglePermissionCommand
||
176 command_id
== kToggleExtensionCommand
;
179 base::string16
NotificationOptionsMenuModel::GetLabelForCommandId(
180 int command_id
) const {
181 // TODO(tfarina,johnnyg): Remove this code if we decide to close notifications
182 // after permissions are revoked.
183 if (command_id
== kTogglePermissionCommand
||
184 command_id
== kToggleExtensionCommand
) {
185 const Notification
& notification
= balloon_
->notification();
186 const GURL
& origin
= notification
.origin_url();
188 DesktopNotificationService
* service
=
189 DesktopNotificationServiceFactory::GetForProfile(balloon_
->profile());
190 if (origin
.SchemeIs(extensions::kExtensionScheme
)) {
191 ExtensionService
* extension_service
=
192 balloon_
->profile()->GetExtensionService();
193 const extensions::Extension
* extension
=
194 extension_service
->extensions()->GetExtensionOrAppByURL(origin
);
196 return l10n_util::GetStringUTF16(
197 extension_service
->IsExtensionEnabled(extension
->id()) ?
198 IDS_EXTENSIONS_DISABLE
:
199 IDS_EXTENSIONS_ENABLE
);
202 if (service
->GetContentSetting(origin
) == CONTENT_SETTING_ALLOW
) {
203 return l10n_util::GetStringFUTF16(
204 IDS_NOTIFICATION_BALLOON_REVOKE_MESSAGE
,
205 notification
.display_source());
207 return l10n_util::GetStringFUTF16(
208 IDS_NOTIFICATION_BALLOON_ENABLE_MESSAGE
,
209 notification
.display_source());
212 } else if (command_id
== kOpenContentSettingsCommand
) {
213 return l10n_util::GetStringUTF16(IDS_NOTIFICATIONS_SETTINGS_BUTTON
);
215 return base::string16();
218 bool NotificationOptionsMenuModel::IsCommandIdChecked(int /* command_id */)
220 // Nothing in the menu is checked.
224 bool NotificationOptionsMenuModel::IsCommandIdEnabled(int /* command_id */)
226 // All the menu options are always enabled.
230 bool NotificationOptionsMenuModel::GetAcceleratorForCommandId(
231 int /* command_id */, ui::Accelerator
* /* accelerator */) {
232 // Currently no accelerators.
236 void NotificationOptionsMenuModel::ExecuteCommand(int command_id
,
238 DesktopNotificationService
* service
=
239 DesktopNotificationServiceFactory::GetForProfile(balloon_
->profile());
240 ExtensionService
* extension_service
=
241 balloon_
->profile()->GetExtensionService();
242 const GURL
& origin
= balloon_
->notification().origin_url();
243 switch (command_id
) {
244 case kTogglePermissionCommand
:
245 if (service
->GetContentSetting(origin
) == CONTENT_SETTING_ALLOW
)
246 service
->DenyPermission(origin
);
248 service
->GrantPermission(origin
);
250 case kToggleExtensionCommand
: {
251 const extensions::Extension
* extension
=
252 extension_service
->extensions()->GetExtensionOrAppByURL(origin
);
254 const std::string
& id
= extension
->id();
255 if (extension_service
->IsExtensionEnabled(id
))
256 extension_service
->DisableExtension(
257 id
, extensions::Extension::DISABLE_USER_ACTION
);
259 extension_service
->EnableExtension(id
);
263 case kOpenContentSettingsCommand
: {
264 chrome::HostDesktopType active_desktop
= chrome::GetActiveDesktop();
265 Browser
* browser
= chrome::FindLastActiveWithProfile(
266 balloon_
->profile(), active_desktop
);
268 // It is possible that there is no browser window (e.g. when there are
269 // background pages).
270 browser
= new Browser(Browser::CreateParams(balloon_
->profile(),
273 chrome::ShowContentSettings(browser
, CONTENT_SETTINGS_TYPE_NOTIFICATIONS
);