diff options
author | johnnyg@chromium.org <johnnyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-12 05:44:26 +0000 |
---|---|---|
committer | johnnyg@chromium.org <johnnyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-12 05:44:26 +0000 |
commit | 4bb33630869981809c47c36c3c18813d6b005d34 (patch) | |
tree | 505252dfeac2de2d02a89d1f7e69ffcdf4affcf5 /chrome/browser/notifications/desktop_notification_service.cc | |
parent | a93244407e205a8619d620ce91bafbdf88eab195 (diff) | |
download | chromium_src-4bb33630869981809c47c36c3c18813d6b005d34.zip chromium_src-4bb33630869981809c47c36c3c18813d6b005d34.tar.gz chromium_src-4bb33630869981809c47c36c3c18813d6b005d34.tar.bz2 |
Browser side support (sans UI) for desktop notifications.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/194108
Review URL: http://codereview.chromium.org/271052
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@28696 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/notifications/desktop_notification_service.cc')
-rw-r--r-- | chrome/browser/notifications/desktop_notification_service.cc | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/chrome/browser/notifications/desktop_notification_service.cc b/chrome/browser/notifications/desktop_notification_service.cc new file mode 100644 index 0000000..0df73d7 --- /dev/null +++ b/chrome/browser/notifications/desktop_notification_service.cc @@ -0,0 +1,234 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/notifications/desktop_notification_service.h" + +#include "app/l10n_util.h" +#include "app/resource_bundle.h" +#include "base/thread.h" +#include "chrome/browser/browser_list.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/chrome_thread.h" +#include "chrome/browser/notifications/notification.h" +#include "chrome/browser/notifications/notification_object_proxy.h" +#include "chrome/browser/notifications/notifications_prefs_cache.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/renderer_host/render_process_host.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/renderer_host/site_instance.h" +#include "chrome/browser/tab_contents/infobar_delegate.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/worker_host/worker_process_host.h" +#include "chrome/common/child_process_host.h" +#include "chrome/common/pref_names.h" +#include "chrome/common/pref_service.h" +#include "chrome/common/render_messages.h" +#include "webkit/api/public/WebNotificationPresenter.h" +#include "grit/chromium_strings.h" +#include "grit/generated_resources.h" +#include "grit/theme_resources.h" + +using WebKit::WebNotificationPresenter; + +// A task object which calls the renderer to inform the web page that the +// permission request has completed. +class NotificationPermissionCallbackTask : public Task { + public: + NotificationPermissionCallbackTask(int process_id, int route_id, + int request_id) + : process_id_(process_id), + route_id_(route_id), + request_id_(request_id) { + } + + virtual void Run() { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + RenderViewHost* host = RenderViewHost::FromID(process_id_, route_id_); + if (host) + host->Send(new ViewMsg_PermissionRequestDone(route_id_, request_id_)); + } + + private: + int process_id_; + int route_id_; + int request_id_; +}; + +// The delegate for the infobar shown when an origin requests notification +// permissions. +class NotificationPermissionInfoBarDelegate : public ConfirmInfoBarDelegate { + public: + NotificationPermissionInfoBarDelegate(TabContents* contents, + const GURL& origin, + int callback_context) + : ConfirmInfoBarDelegate(contents), + origin_(origin), + profile_(contents->profile()), + process_id_(contents->process()->id()), + route_id_(contents->render_view_host()->routing_id()), + callback_context_(callback_context), + action_taken_(false) { + } + + // Overridden from ConfirmInfoBarDelegate: + virtual void InfoBarClosed() { + if (!action_taken_) + UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Ignored", 1); + + base::Thread* io_thread = g_browser_process->io_thread(); + if (io_thread && io_thread->message_loop()) { + io_thread->message_loop()->PostTask(FROM_HERE, + new NotificationPermissionCallbackTask(process_id_, route_id_, + callback_context_)); + } + + delete this; + } + + virtual std::wstring GetMessageText() const { + return l10n_util::GetStringF(IDS_NOTIFICATION_PERMISSIONS, + UTF8ToWide(origin_.spec())); + } + + virtual SkBitmap* GetIcon() const { + return ResourceBundle::GetSharedInstance().GetBitmapNamed( + IDR_PRODUCT_ICON_32); + } + + virtual int GetButtons() const { + return BUTTON_OK | BUTTON_CANCEL | BUTTON_OK_DEFAULT; + } + + virtual std::wstring GetButtonLabel(InfoBarButton button) const { + return button == BUTTON_OK ? + l10n_util::GetString(IDS_NOTIFICATION_PERMISSION_YES) : + l10n_util::GetString(IDS_NOTIFICATION_PERMISSION_NO); + } + + virtual bool Accept() { + UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Allowed", 1); + profile_->GetDesktopNotificationService()->GrantPermission(origin_); + action_taken_ = true; + return true; + } + + virtual bool Cancel() { + UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Denied", 1); + profile_->GetDesktopNotificationService()->DenyPermission(origin_); + action_taken_ = true; + return true; + } + + private: + // The origin we are asking for permissions on. + GURL origin_; + + // The Profile that we restore sessions from. + Profile* profile_; + + // The callback information that tells us how to respond to javascript via + // the correct RenderView. + int process_id_; + int route_id_; + int callback_context_; + + // Whether the user clicked one of the buttons. + bool action_taken_; + + DISALLOW_COPY_AND_ASSIGN(NotificationPermissionInfoBarDelegate); +}; + +DesktopNotificationService::DesktopNotificationService(Profile* profile, + NotificationUIManager* ui_manager) + : profile_(profile), + ui_manager_(ui_manager) { + InitPrefs(); +} + +DesktopNotificationService::~DesktopNotificationService() { +} + +// Initialize the cache with the allowed and denied origins, or +// create the preferences if they don't exist yet. +void DesktopNotificationService::InitPrefs() { + PrefService* prefs = profile_->GetPrefs(); + ListValue* allowed_sites = NULL; + ListValue* denied_sites = NULL; + + if (prefs->FindPreference(prefs::kDesktopNotificationAllowedOrigins)) + allowed_sites = + prefs->GetMutableList(prefs::kDesktopNotificationAllowedOrigins); + else + prefs->RegisterListPref(prefs::kDesktopNotificationAllowedOrigins); + + if (prefs->FindPreference(prefs::kDesktopNotificationDeniedOrigins)) + denied_sites = + prefs->GetMutableList(prefs::kDesktopNotificationDeniedOrigins); + else + prefs->RegisterListPref(prefs::kDesktopNotificationDeniedOrigins); + + prefs_cache_ = new NotificationsPrefsCache(allowed_sites, denied_sites); +} + +void DesktopNotificationService::GrantPermission(const GURL& origin) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + PrefService* prefs = profile_->GetPrefs(); + ListValue* allowed_sites = + prefs->GetMutableList(prefs::kDesktopNotificationAllowedOrigins); + ListValue* denied_sites = + prefs->GetMutableList(prefs::kDesktopNotificationDeniedOrigins); + // Remove from the black-list and add to the white-list. + StringValue* value = new StringValue(origin.spec()); + denied_sites->Remove(*value); + allowed_sites->Append(value); + prefs->ScheduleSavePersistentPrefs(); + + // Schedule a cache update on the IO thread. + base::Thread* io_thread = g_browser_process->io_thread(); + if (io_thread && io_thread->message_loop()) { + io_thread->message_loop()->PostTask(FROM_HERE, + NewRunnableMethod(prefs_cache_.get(), + &NotificationsPrefsCache::CacheAllowedOrigin, + origin)); + } +} + +void DesktopNotificationService::DenyPermission(const GURL& origin) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + PrefService* prefs = profile_->GetPrefs(); + ListValue* allowed_sites = + prefs->GetMutableList(prefs::kDesktopNotificationAllowedOrigins); + ListValue* denied_sites = + prefs->GetMutableList(prefs::kDesktopNotificationDeniedOrigins); + StringValue* value = new StringValue(origin.spec()); + // Remove from the white-list and add to the black-list. + allowed_sites->Remove(*value); + denied_sites->Append(value); + prefs->ScheduleSavePersistentPrefs(); + + // Schedule a cache update on the IO thread. + base::Thread* io_thread = g_browser_process->io_thread(); + if (io_thread && io_thread->message_loop()) { + io_thread->message_loop()->PostTask(FROM_HERE, + NewRunnableMethod(prefs_cache_.get(), + &NotificationsPrefsCache::CacheDeniedOrigin, + origin)); + } +} + +void DesktopNotificationService::RequestPermission( + const GURL& origin, int callback_context) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + // Show an info bar requesting permission. + Browser* browser = BrowserList::GetLastActive(); + if (!browser) { + // Reached during ui tests. + return; + } + TabContents* tab = browser->GetSelectedTabContents(); + if (!tab) + return; + tab->AddInfoBar(new NotificationPermissionInfoBarDelegate(tab, origin, + callback_context)); +} |