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 |