Chromium Code Reviews| Index: chrome/browser/notifications/desktop_notification_service.cc |
| diff --git a/chrome/browser/notifications/desktop_notification_service.cc b/chrome/browser/notifications/desktop_notification_service.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..aa40e15cf9fff8394070291aeb20201fdcd0ad27 |
| --- /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_ui_manager.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() { |
|
michaeln
2009/10/10 19:10:51
maybe DCHECK(ChromeThread::CurrentlyOn(ChromeThrea
|
| + 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 { |
|
michaeln
2009/10/10 19:10:51
I'm not familiar with the infobar ui infrastructur
|
| + 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)); |
| +} |