desktop_notification_service.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/notifications/desktop_notification_service.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/utf_string_conversions.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/api/infobars/confirm_infobar_delegate.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/content_settings/content_settings_details.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/content_settings/content_settings_provider.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/content_settings/host_content_settings_map.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/infobars/infobar_tab_helper.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/notifications/desktop_notification_service_factory.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/notifications/notification.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/notifications/notification_object_proxy.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/notifications/notification_ui_manager.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prefs/pref_service.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prefs/scoped_user_pref_update.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tab_contents/tab_contents.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/web_ui_util.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_notification_types.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/content_settings.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/content_settings_pattern.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/show_desktop_notification_params.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/browser_resources.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/chromium_strings.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/escape.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHost; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebNotificationPresenter; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebTextDirection; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using WebKit::WebSecurityOrigin; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ContentSetting kDefaultSetting = CONTENT_SETTING_ASK; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NotificationPermissionInfoBarDelegate -------------------------------------- 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The delegate for the infobar shown when an origin requests notification 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// permissions. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NotificationPermissionInfoBarDelegate : public ConfirmInfoBarDelegate { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotificationPermissionInfoBarDelegate( 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InfoBarTabHelper* infobar_helper, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DesktopNotificationService* notification_service, 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& origin, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& display_name, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int process_id, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int route_id, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int callback_context); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~NotificationPermissionInfoBarDelegate(); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ConfirmInfoBarDelegate: 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual gfx::Image* GetIcon() const OVERRIDE; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual Type GetInfoBarType() const OVERRIDE; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual string16 GetMessageText() const OVERRIDE; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Accept() OVERRIDE; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Cancel() OVERRIDE; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The origin we are asking for permissions on. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL origin_; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The display name for the origin to be displayed. Will be different from 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // origin_ for extensions. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 display_name_; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The notification service to be used. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DesktopNotificationService* notification_service_; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The callback information that tells us how to respond to javascript via 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the correct RenderView. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int process_id_; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int route_id_; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int callback_context_; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Whether the user clicked one of the buttons. 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool action_taken_; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(NotificationPermissionInfoBarDelegate); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NotificationPermissionInfoBarDelegate::NotificationPermissionInfoBarDelegate( 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InfoBarTabHelper* infobar_helper, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DesktopNotificationService* notification_service, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& origin, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& display_name, 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int process_id, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int route_id, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int callback_context) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ConfirmInfoBarDelegate(infobar_helper), 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_(origin), 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) display_name_(display_name), 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_service_(notification_service), 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_id_(process_id), 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) route_id_(route_id), 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_context_(callback_context), 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) action_taken_(false) { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NotificationPermissionInfoBarDelegate:: 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~NotificationPermissionInfoBarDelegate() { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!action_taken_) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Ignored", 1); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderViewHost* host = RenderViewHost::FromID(process_id_, route_id_); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host->DesktopNotificationPermissionRequestDone(callback_context_); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Image* NotificationPermissionInfoBarDelegate::GetIcon() const { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &ResourceBundle::GetSharedInstance().GetNativeImageNamed( 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDR_INFOBAR_DESKTOP_NOTIFICATIONS); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InfoBarDelegate::Type 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotificationPermissionInfoBarDelegate::GetInfoBarType() const { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PAGE_ACTION_TYPE; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 NotificationPermissionInfoBarDelegate::GetMessageText() const { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return l10n_util::GetStringFUTF16(IDS_NOTIFICATION_PERMISSIONS, 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) display_name_); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 NotificationPermissionInfoBarDelegate::GetButtonLabel( 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InfoBarButton button) const { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return l10n_util::GetStringUTF16((button == BUTTON_OK) ? 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDS_NOTIFICATION_PERMISSION_YES : IDS_NOTIFICATION_PERMISSION_NO); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NotificationPermissionInfoBarDelegate::Accept() { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Allowed", 1); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_service_->GrantPermission(origin_); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) action_taken_ = true; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NotificationPermissionInfoBarDelegate::Cancel() { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Denied", 1); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_service_->DenyPermission(origin_); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) action_taken_ = true; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DesktopNotificationService ------------------------------------------------- 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 DesktopNotificationService::CreateDataUrl( 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& icon_url, const string16& title, const string16& body, 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebTextDirection dir) { 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int resource; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> subst; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (icon_url.is_valid()) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource = IDR_NOTIFICATION_ICON_HTML; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subst.push_back(icon_url.spec()); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subst.push_back(net::EscapeForHTML(UTF16ToUTF8(title))); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subst.push_back(net::EscapeForHTML(UTF16ToUTF8(body))); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // icon float position 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subst.push_back(dir == WebKit::WebTextDirectionRightToLeft ? 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "right" : "left"); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (title.empty() || body.empty()) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource = IDR_NOTIFICATION_1LINE_HTML; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 line = title.empty() ? body : title; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Strings are div names in the template file. 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 line_name = title.empty() ? ASCIIToUTF16("description") 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ASCIIToUTF16("title"); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subst.push_back(net::EscapeForHTML(UTF16ToUTF8(line_name))); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subst.push_back(net::EscapeForHTML(UTF16ToUTF8(line))); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource = IDR_NOTIFICATION_2LINE_HTML; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subst.push_back(net::EscapeForHTML(UTF16ToUTF8(title))); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subst.push_back(net::EscapeForHTML(UTF16ToUTF8(body))); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // body text direction 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) subst.push_back(dir == WebKit::WebTextDirectionRightToLeft ? 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "rtl" : "ltr"); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CreateDataUrl(resource, subst); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 DesktopNotificationService::CreateDataUrl( 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int resource, const std::vector<std::string>& subst) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::StringPiece template_html( 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceBundle::GetSharedInstance().GetRawDataResource( 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resource)); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (template_html.empty()) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "unable to load template. ID: " << resource; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return string16(); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string data = ReplaceStringPlaceholders(template_html, subst, NULL); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return UTF8ToUTF16("data:text/html;charset=utf-8," + 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::EscapeQueryParamValue(data, false)); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string DesktopNotificationService::AddNotification( 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& origin_url, 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& title, 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& message, 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& icon_url, 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& replace_id, 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotificationDelegate* delegate, 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile) { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_ASH) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For Ash create a non-HTML notification with |icon_url|. 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Notification notification(GURL(), icon_url, title, message, 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebKit::WebTextDirectionDefault, 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16(), replace_id, delegate); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_browser_process->notification_ui_manager()->Add(notification, profile); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return notification.notification_id(); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate a data URL embedding the icon URL, title, and message. 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL content_url(CreateDataUrl( 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_url, title, message, WebKit::WebTextDirectionDefault)); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Notification notification( 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL(), content_url, string16(), replace_id, delegate); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_browser_process->notification_ui_manager()->Add(notification, profile); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return notification.notification_id(); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string DesktopNotificationService::AddIconNotification( 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& origin_url, 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& title, 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& message, 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const gfx::ImageSkia& icon, 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& replace_id, 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotificationDelegate* delegate, 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile) { 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_ASH) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For Ash create a non-HTML notification with |icon|. 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Notification notification(GURL(), icon, title, message, 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebKit::WebTextDirectionDefault, 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16(), replace_id, delegate); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_browser_process->notification_ui_manager()->Add(notification, profile); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return notification.notification_id(); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL icon_url; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!icon.isNull()) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_url = GURL(web_ui_util::GetBitmapDataUrl(*icon.bitmap())); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddNotification( 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_url, title, message, icon_url, replace_id, delegate, profile); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::RemoveNotification( 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& notification_id) { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_browser_process->notification_ui_manager()->CancelById(notification_id); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DesktopNotificationService::DesktopNotificationService(Profile* profile, 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotificationUIManager* ui_manager) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : profile_(profile), 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_manager_(ui_manager) { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartObserving(); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DesktopNotificationService::~DesktopNotificationService() { 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopObserving(); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::StartObserving() { 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!profile_->IsOffTheRecord()) { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile_)); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED, 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile_)); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::StopObserving() { 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_registrar_.RemoveAll(); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::GrantPermission(const GURL& origin) { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContentSettingsPattern primary_pattern = 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContentSettingsPattern::FromURLNoWildcard(origin); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->GetHostContentSettingsMap()->SetContentSetting( 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) primary_pattern, 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContentSettingsPattern::Wildcard(), 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONTENT_SETTINGS_TYPE_NOTIFICATIONS, 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NO_RESOURCE_IDENTIFIER, 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONTENT_SETTING_ALLOW); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::DenyPermission(const GURL& origin) { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContentSettingsPattern primary_pattern = 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContentSettingsPattern::FromURLNoWildcard(origin); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->GetHostContentSettingsMap()->SetContentSetting( 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) primary_pattern, 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContentSettingsPattern::Wildcard(), 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONTENT_SETTINGS_TYPE_NOTIFICATIONS, 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NO_RESOURCE_IDENTIFIER, 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONTENT_SETTING_BLOCK); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::Observe( 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int type, 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) { 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove all notifications currently shown or queued by the extension 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which was unloaded. Don't use GetUIManager() here, because this may 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // get called during shutdown. 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const extensions::Extension* extension = 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<extensions::UnloadedExtensionInfo>(details)->extension; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension && 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_browser_process && g_browser_process->notification_ui_manager()) { 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_browser_process->notification_ui_manager()-> 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CancelAllBySourceOrigin(extension->url()); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (type == chrome::NOTIFICATION_PROFILE_DESTROYED) { 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopObserving(); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContentSetting DesktopNotificationService::GetDefaultContentSetting( 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* provider_id) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return profile_->GetHostContentSettingsMap()->GetDefaultContentSetting( 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONTENT_SETTINGS_TYPE_NOTIFICATIONS, provider_id); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::SetDefaultContentSetting( 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContentSetting setting) { 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->GetHostContentSettingsMap()->SetDefaultContentSetting( 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONTENT_SETTINGS_TYPE_NOTIFICATIONS, setting); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::ResetToDefaultContentSetting() { 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->GetHostContentSettingsMap()->SetDefaultContentSetting( 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONTENT_SETTINGS_TYPE_NOTIFICATIONS, CONTENT_SETTING_DEFAULT); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::GetNotificationsSettings( 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContentSettingsForOneType* settings) { 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->GetHostContentSettingsMap()->GetSettingsForOneType( 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONTENT_SETTINGS_TYPE_NOTIFICATIONS, 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NO_RESOURCE_IDENTIFIER, 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) settings); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::ClearSetting( 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ContentSettingsPattern& pattern) { 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->GetHostContentSettingsMap()->SetContentSetting( 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pattern, 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContentSettingsPattern::Wildcard(), 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONTENT_SETTINGS_TYPE_NOTIFICATIONS, 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NO_RESOURCE_IDENTIFIER, 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONTENT_SETTING_DEFAULT); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::ResetAllOrigins() { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->GetHostContentSettingsMap()->ClearSettingsForOneType( 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONTENT_SETTINGS_TYPE_NOTIFICATIONS); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ContentSetting DesktopNotificationService::GetContentSetting( 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& origin) { 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return profile_->GetHostContentSettingsMap()->GetContentSetting( 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin, 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin, 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONTENT_SETTINGS_TYPE_NOTIFICATIONS, 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NO_RESOURCE_IDENTIFIER); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::RequestPermission( 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& origin, int process_id, int route_id, int callback_context, 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebContents* contents) { 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If |origin| hasn't been seen before and the default content setting for 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notifications is "ask", show an infobar. 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The cache can only answer queries on the IO thread once it's initialized, 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so don't ask the cache. 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContentSetting setting = GetContentSetting(origin); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (setting == CONTENT_SETTING_ASK) { 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Show an info bar requesting permission. 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InfoBarTabHelper* infobar_tab_helper = 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InfoBarTabHelper::FromWebContents(contents); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |infobar_tab_helper| may be NULL, e.g., if this request originated in a 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // browser action popup, extension background page, or any HTML that runs 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // outside of a tab. 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (infobar_tab_helper) { 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) infobar_tab_helper->AddInfoBar(new NotificationPermissionInfoBarDelegate( 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) infobar_tab_helper, 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DesktopNotificationServiceFactory::GetForProfile( 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile::FromBrowserContext(contents->GetBrowserContext())), 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin, 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DisplayNameForOrigin(origin), 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process_id, 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) route_id, 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_context)); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Notify renderer immediately. 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderViewHost* host = RenderViewHost::FromID(process_id, route_id); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host->DesktopNotificationPermissionRequestDone(callback_context); 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_WIN) 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::ShowNotification( 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Notification& notification) { 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetUIManager()->Add(notification, profile_); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DesktopNotificationService::CancelDesktopNotification( 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int process_id, int route_id, int notification_id) { 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<NotificationObjectProxy> proxy( 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new NotificationObjectProxy(process_id, route_id, notification_id, 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false)); 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetUIManager()->CancelById(proxy->id()); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // OS_WIN 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DesktopNotificationService::ShowDesktopNotification( 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::ShowDesktopNotificationHostMsgParams& params, 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int process_id, int route_id, DesktopNotificationSource source) { 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& origin = params.origin; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotificationObjectProxy* proxy = 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new NotificationObjectProxy(process_id, route_id, 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.notification_id, 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source == WorkerNotification); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 display_source = DisplayNameForOrigin(origin); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (params.is_html) { 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShowNotification(Notification(origin, params.contents_url, display_source, 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.replace_id, proxy)); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShowNotification(Notification(origin, params.icon_url, params.title, 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.body, params.direction, display_source, params.replace_id, 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy)); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 DesktopNotificationService::DisplayNameForOrigin( 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& origin) { 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the source is an extension, lookup the display name. 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (origin.SchemeIs(chrome::kExtensionScheme)) { 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionService* extension_service = profile_->GetExtensionService(); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension_service) { 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const extensions::Extension* extension = 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_service->extensions()->GetExtensionOrAppByURL( 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionURLInfo( 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebSecurityOrigin::createFromString( 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UTF8ToUTF16(origin.spec())), 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin)); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension) 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return UTF8ToUTF16(extension->name()); 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return UTF8ToUTF16(origin.host()); 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DesktopNotificationService::NotifySettingsChange() { 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::current()->Notify( 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_DESKTOP_NOTIFICATION_SETTINGS_CHANGED, 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<DesktopNotificationService>(this), 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::NoDetails()); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NotificationUIManager* DesktopNotificationService::GetUIManager() { 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We defer setting ui_manager_ to the global singleton until we need it 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in order to avoid UI dependent construction during startup. 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ui_manager_) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_manager_ = g_browser_process->notification_ui_manager(); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui_manager_; 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebKit::WebNotificationPresenter::Permission 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DesktopNotificationService::HasPermission(const GURL& origin) { 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostContentSettingsMap* host_content_settings_map = 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->GetHostContentSettingsMap(); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ContentSetting setting = host_content_settings_map->GetContentSetting( 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin, 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin, 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONTENT_SETTINGS_TYPE_NOTIFICATIONS, 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NO_RESOURCE_IDENTIFIER); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (setting == CONTENT_SETTING_ALLOW) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WebKit::WebNotificationPresenter::PermissionAllowed; 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (setting == CONTENT_SETTING_BLOCK) 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WebKit::WebNotificationPresenter::PermissionDenied; 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (setting == CONTENT_SETTING_ASK) 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WebKit::WebNotificationPresenter::PermissionNotAllowed; 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Invalid notifications settings value: " << setting; 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return WebKit::WebNotificationPresenter::PermissionNotAllowed; 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 519