Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2009 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. | |
| 4 | |
| 5 #include "chrome/browser/notifications/desktop_notification_service.h" | |
| 6 | |
| 7 #include "app/l10n_util.h" | |
| 8 #include "app/resource_bundle.h" | |
| 9 #include "base/thread.h" | |
| 10 #include "chrome/browser/browser_list.h" | |
| 11 #include "chrome/browser/browser_process.h" | |
| 12 #include "chrome/browser/chrome_thread.h" | |
| 13 #include "chrome/browser/notifications/notification.h" | |
| 14 #include "chrome/browser/notifications/notification_ui_manager.h" | |
| 15 #include "chrome/browser/notifications/notification_object_proxy.h" | |
| 16 #include "chrome/browser/notifications/notifications_prefs_cache.h" | |
| 17 #include "chrome/browser/profile.h" | |
| 18 #include "chrome/browser/renderer_host/render_process_host.h" | |
| 19 #include "chrome/browser/renderer_host/render_view_host.h" | |
| 20 #include "chrome/browser/renderer_host/site_instance.h" | |
| 21 #include "chrome/browser/tab_contents/infobar_delegate.h" | |
| 22 #include "chrome/browser/tab_contents/tab_contents.h" | |
| 23 #include "chrome/browser/worker_host/worker_process_host.h" | |
| 24 #include "chrome/common/child_process_host.h" | |
| 25 #include "chrome/common/pref_names.h" | |
| 26 #include "chrome/common/pref_service.h" | |
| 27 #include "chrome/common/render_messages.h" | |
| 28 #include "webkit/api/public/WebNotificationPresenter.h" | |
| 29 #include "grit/chromium_strings.h" | |
| 30 #include "grit/generated_resources.h" | |
| 31 #include "grit/theme_resources.h" | |
| 32 | |
| 33 using WebKit::WebNotificationPresenter; | |
| 34 | |
| 35 // A task object which calls the renderer to inform the web page that the | |
| 36 // permission request has completed. | |
| 37 class NotificationPermissionCallbackTask : public Task { | |
| 38 public: | |
| 39 NotificationPermissionCallbackTask(int process_id, int route_id, | |
| 40 int request_id) | |
| 41 : process_id_(process_id), | |
| 42 route_id_(route_id), | |
| 43 request_id_(request_id) { | |
| 44 } | |
| 45 | |
| 46 virtual void Run() { | |
|
michaeln
2009/10/10 19:10:51
maybe DCHECK(ChromeThread::CurrentlyOn(ChromeThrea
| |
| 47 RenderViewHost* host = RenderViewHost::FromID(process_id_, route_id_); | |
| 48 if (host) | |
| 49 host->Send(new ViewMsg_PermissionRequestDone(route_id_, request_id_)); | |
| 50 } | |
| 51 | |
| 52 private: | |
| 53 int process_id_; | |
| 54 int route_id_; | |
| 55 int request_id_; | |
| 56 }; | |
| 57 | |
| 58 // The delegate for the infobar shown when an origin requests notification | |
| 59 // permissions. | |
| 60 class NotificationPermissionInfoBarDelegate : public ConfirmInfoBarDelegate { | |
|
michaeln
2009/10/10 19:10:51
I'm not familiar with the infobar ui infrastructur
| |
| 61 public: | |
| 62 NotificationPermissionInfoBarDelegate(TabContents* contents, | |
| 63 const GURL& origin, | |
| 64 int callback_context) | |
| 65 : ConfirmInfoBarDelegate(contents), | |
| 66 origin_(origin), | |
| 67 profile_(contents->profile()), | |
| 68 process_id_(contents->process()->id()), | |
| 69 route_id_(contents->render_view_host()->routing_id()), | |
| 70 callback_context_(callback_context), | |
| 71 action_taken_(false) { | |
| 72 } | |
| 73 | |
| 74 // Overridden from ConfirmInfoBarDelegate: | |
| 75 virtual void InfoBarClosed() { | |
| 76 if (!action_taken_) | |
| 77 UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Ignored", 1); | |
| 78 | |
| 79 base::Thread* io_thread = g_browser_process->io_thread(); | |
| 80 if (io_thread && io_thread->message_loop()) { | |
| 81 io_thread->message_loop()->PostTask(FROM_HERE, | |
| 82 new NotificationPermissionCallbackTask(process_id_, route_id_, | |
| 83 callback_context_)); | |
| 84 } | |
| 85 | |
| 86 delete this; | |
| 87 } | |
| 88 | |
| 89 virtual std::wstring GetMessageText() const { | |
| 90 return l10n_util::GetStringF(IDS_NOTIFICATION_PERMISSIONS, | |
| 91 UTF8ToWide(origin_.spec())); | |
| 92 } | |
| 93 | |
| 94 virtual SkBitmap* GetIcon() const { | |
| 95 return ResourceBundle::GetSharedInstance().GetBitmapNamed( | |
| 96 IDR_PRODUCT_ICON_32); | |
| 97 } | |
| 98 | |
| 99 virtual int GetButtons() const { | |
| 100 return BUTTON_OK | BUTTON_CANCEL | BUTTON_OK_DEFAULT; | |
| 101 } | |
| 102 | |
| 103 virtual std::wstring GetButtonLabel(InfoBarButton button) const { | |
| 104 return button == BUTTON_OK ? | |
| 105 l10n_util::GetString(IDS_NOTIFICATION_PERMISSION_YES) : | |
| 106 l10n_util::GetString(IDS_NOTIFICATION_PERMISSION_NO); | |
| 107 } | |
| 108 | |
| 109 virtual bool Accept() { | |
| 110 UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Allowed", 1); | |
| 111 profile_->GetDesktopNotificationService()->GrantPermission(origin_); | |
| 112 action_taken_ = true; | |
| 113 return true; | |
| 114 } | |
| 115 | |
| 116 virtual bool Cancel() { | |
| 117 UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Denied", 1); | |
| 118 profile_->GetDesktopNotificationService()->DenyPermission(origin_); | |
| 119 action_taken_ = true; | |
| 120 return true; | |
| 121 } | |
| 122 | |
| 123 private: | |
| 124 // The origin we are asking for permissions on. | |
| 125 GURL origin_; | |
| 126 | |
| 127 // The Profile that we restore sessions from. | |
| 128 Profile* profile_; | |
| 129 | |
| 130 // The callback information that tells us how to respond to javascript via | |
| 131 // the correct RenderView. | |
| 132 int process_id_; | |
| 133 int route_id_; | |
| 134 int callback_context_; | |
| 135 | |
| 136 // Whether the user clicked one of the buttons. | |
| 137 bool action_taken_; | |
| 138 | |
| 139 DISALLOW_COPY_AND_ASSIGN(NotificationPermissionInfoBarDelegate); | |
| 140 }; | |
| 141 | |
| 142 DesktopNotificationService::DesktopNotificationService(Profile* profile, | |
| 143 NotificationUIManager* ui_manager) | |
| 144 : profile_(profile), | |
| 145 ui_manager_(ui_manager) { | |
| 146 InitPrefs(); | |
| 147 } | |
| 148 | |
| 149 DesktopNotificationService::~DesktopNotificationService() { | |
| 150 } | |
| 151 | |
| 152 // Initialize the cache with the allowed and denied origins, or | |
| 153 // create the preferences if they don't exist yet. | |
| 154 void DesktopNotificationService::InitPrefs() { | |
| 155 PrefService* prefs = profile_->GetPrefs(); | |
| 156 ListValue* allowed_sites = NULL; | |
| 157 ListValue* denied_sites = NULL; | |
| 158 | |
| 159 if (prefs->FindPreference(prefs::kDesktopNotificationAllowedOrigins)) | |
| 160 allowed_sites = | |
| 161 prefs->GetMutableList(prefs::kDesktopNotificationAllowedOrigins); | |
| 162 else | |
| 163 prefs->RegisterListPref(prefs::kDesktopNotificationAllowedOrigins); | |
| 164 | |
| 165 if (prefs->FindPreference(prefs::kDesktopNotificationDeniedOrigins)) | |
| 166 denied_sites = | |
| 167 prefs->GetMutableList(prefs::kDesktopNotificationDeniedOrigins); | |
| 168 else | |
| 169 prefs->RegisterListPref(prefs::kDesktopNotificationDeniedOrigins); | |
| 170 | |
| 171 prefs_cache_ = new NotificationsPrefsCache(allowed_sites, denied_sites); | |
| 172 } | |
| 173 | |
| 174 void DesktopNotificationService::GrantPermission(const GURL& origin) { | |
| 175 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | |
| 176 PrefService* prefs = profile_->GetPrefs(); | |
| 177 ListValue* allowed_sites = | |
| 178 prefs->GetMutableList(prefs::kDesktopNotificationAllowedOrigins); | |
| 179 ListValue* denied_sites = | |
| 180 prefs->GetMutableList(prefs::kDesktopNotificationDeniedOrigins); | |
| 181 // Remove from the black-list and add to the white-list. | |
| 182 StringValue* value = new StringValue(origin.spec()); | |
| 183 denied_sites->Remove(*value); | |
| 184 allowed_sites->Append(value); | |
| 185 prefs->ScheduleSavePersistentPrefs(); | |
| 186 | |
| 187 // Schedule a cache update on the IO thread. | |
| 188 base::Thread* io_thread = g_browser_process->io_thread(); | |
| 189 if (io_thread && io_thread->message_loop()) { | |
| 190 io_thread->message_loop()->PostTask(FROM_HERE, | |
| 191 NewRunnableMethod(prefs_cache_.get(), | |
| 192 &NotificationsPrefsCache::CacheAllowedOrigin, | |
| 193 origin)); | |
| 194 } | |
| 195 } | |
| 196 | |
| 197 void DesktopNotificationService::DenyPermission(const GURL& origin) { | |
| 198 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | |
| 199 PrefService* prefs = profile_->GetPrefs(); | |
| 200 ListValue* allowed_sites = | |
| 201 prefs->GetMutableList(prefs::kDesktopNotificationAllowedOrigins); | |
| 202 ListValue* denied_sites = | |
| 203 prefs->GetMutableList(prefs::kDesktopNotificationDeniedOrigins); | |
| 204 StringValue* value = new StringValue(origin.spec()); | |
| 205 // Remove from the white-list and add to the black-list. | |
| 206 allowed_sites->Remove(*value); | |
| 207 denied_sites->Append(value); | |
| 208 prefs->ScheduleSavePersistentPrefs(); | |
| 209 | |
| 210 // Schedule a cache update on the IO thread. | |
| 211 base::Thread* io_thread = g_browser_process->io_thread(); | |
| 212 if (io_thread && io_thread->message_loop()) { | |
| 213 io_thread->message_loop()->PostTask(FROM_HERE, | |
| 214 NewRunnableMethod(prefs_cache_.get(), | |
| 215 &NotificationsPrefsCache::CacheDeniedOrigin, | |
| 216 origin)); | |
| 217 } | |
| 218 } | |
| 219 | |
| 220 void DesktopNotificationService::RequestPermission( | |
| 221 const GURL& origin, int callback_context) { | |
| 222 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | |
| 223 // Show an info bar requesting permission. | |
| 224 Browser* browser = BrowserList::GetLastActive(); | |
| 225 if (!browser) { | |
| 226 // Reached during ui tests. | |
| 227 return; | |
| 228 } | |
| 229 TabContents* tab = browser->GetSelectedTabContents(); | |
| 230 if (!tab) | |
| 231 return; | |
| 232 tab->AddInfoBar(new NotificationPermissionInfoBarDelegate(tab, origin, | |
| 233 callback_context)); | |
| 234 } | |
| OLD | NEW |