OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/notifications/desktop_notification_service.h" | 5 #include "chrome/browser/notifications/desktop_notification_service.h" |
6 | 6 |
7 #include "app/l10n_util.h" | 7 #include "app/l10n_util.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/threading/thread.h" | 9 #include "base/threading/thread.h" |
10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
11 #include "chrome/browser/browser_child_process_host.h" | 11 #include "chrome/browser/browser_child_process_host.h" |
(...skipping 24 matching lines...) Expand all Loading... |
36 #include "grit/theme_resources.h" | 36 #include "grit/theme_resources.h" |
37 #include "net/base/escape.h" | 37 #include "net/base/escape.h" |
38 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNotificationPresen
ter.h" | 38 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNotificationPresen
ter.h" |
39 #include "ui/base/resource/resource_bundle.h" | 39 #include "ui/base/resource/resource_bundle.h" |
40 | 40 |
41 using WebKit::WebNotificationPresenter; | 41 using WebKit::WebNotificationPresenter; |
42 using WebKit::WebTextDirection; | 42 using WebKit::WebTextDirection; |
43 | 43 |
44 const ContentSetting kDefaultSetting = CONTENT_SETTING_ASK; | 44 const ContentSetting kDefaultSetting = CONTENT_SETTING_ASK; |
45 | 45 |
| 46 // NotificationPermissionCallbackTask ----------------------------------------- |
| 47 |
| 48 // A task object which calls the renderer to inform the web page that the |
| 49 // permission request has completed. |
| 50 class NotificationPermissionCallbackTask : public Task { |
| 51 public: |
| 52 NotificationPermissionCallbackTask(int process_id, |
| 53 int route_id, |
| 54 int request_id); |
| 55 virtual ~NotificationPermissionCallbackTask(); |
| 56 |
| 57 private: |
| 58 virtual void Run(); |
| 59 |
| 60 int process_id_; |
| 61 int route_id_; |
| 62 int request_id_; |
| 63 }; |
| 64 |
| 65 NotificationPermissionCallbackTask::NotificationPermissionCallbackTask( |
| 66 int process_id, |
| 67 int route_id, |
| 68 int request_id) |
| 69 : process_id_(process_id), |
| 70 route_id_(route_id), |
| 71 request_id_(request_id) { |
| 72 } |
| 73 |
| 74 NotificationPermissionCallbackTask::~NotificationPermissionCallbackTask() { |
| 75 } |
| 76 |
| 77 void NotificationPermissionCallbackTask::Run() { |
| 78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 79 RenderViewHost* host = RenderViewHost::FromID(process_id_, route_id_); |
| 80 if (host) |
| 81 host->Send(new ViewMsg_PermissionRequestDone(route_id_, request_id_)); |
| 82 } |
| 83 |
| 84 |
| 85 // NotificationPermissionInfoBarDelegate -------------------------------------- |
| 86 |
| 87 // The delegate for the infobar shown when an origin requests notification |
| 88 // permissions. |
| 89 class NotificationPermissionInfoBarDelegate : public ConfirmInfoBarDelegate { |
| 90 public: |
| 91 NotificationPermissionInfoBarDelegate(TabContents* contents, |
| 92 const GURL& origin, |
| 93 const string16& display_name, |
| 94 int process_id, |
| 95 int route_id, |
| 96 int callback_context); |
| 97 |
| 98 private: |
| 99 virtual ~NotificationPermissionInfoBarDelegate(); |
| 100 |
| 101 // ConfirmInfoBarDelegate: |
| 102 virtual void InfoBarClosed(); |
| 103 virtual SkBitmap* GetIcon() const; |
| 104 virtual Type GetInfoBarType() const; |
| 105 virtual string16 GetMessageText() const; |
| 106 virtual int GetButtons() const; |
| 107 virtual string16 GetButtonLabel(InfoBarButton button) const; |
| 108 virtual bool Accept(); |
| 109 virtual bool Cancel(); |
| 110 |
| 111 // The origin we are asking for permissions on. |
| 112 GURL origin_; |
| 113 |
| 114 // The display name for the origin to be displayed. Will be different from |
| 115 // origin_ for extensions. |
| 116 string16 display_name_; |
| 117 |
| 118 // The Profile that we restore sessions from. |
| 119 Profile* profile_; |
| 120 |
| 121 // The callback information that tells us how to respond to javascript via |
| 122 // the correct RenderView. |
| 123 int process_id_; |
| 124 int route_id_; |
| 125 int callback_context_; |
| 126 |
| 127 // Whether the user clicked one of the buttons. |
| 128 bool action_taken_; |
| 129 |
| 130 DISALLOW_COPY_AND_ASSIGN(NotificationPermissionInfoBarDelegate); |
| 131 }; |
| 132 |
| 133 NotificationPermissionInfoBarDelegate::NotificationPermissionInfoBarDelegate( |
| 134 TabContents* contents, |
| 135 const GURL& origin, |
| 136 const string16& display_name, |
| 137 int process_id, |
| 138 int route_id, |
| 139 int callback_context) |
| 140 : ConfirmInfoBarDelegate(contents), |
| 141 origin_(origin), |
| 142 display_name_(display_name), |
| 143 profile_(contents->profile()), |
| 144 process_id_(process_id), |
| 145 route_id_(route_id), |
| 146 callback_context_(callback_context), |
| 147 action_taken_(false) { |
| 148 } |
| 149 |
| 150 NotificationPermissionInfoBarDelegate:: |
| 151 ~NotificationPermissionInfoBarDelegate() { |
| 152 } |
| 153 |
| 154 void NotificationPermissionInfoBarDelegate::InfoBarClosed() { |
| 155 if (!action_taken_) |
| 156 UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Ignored", 1); |
| 157 |
| 158 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, |
| 159 new NotificationPermissionCallbackTask(process_id_, route_id_, |
| 160 callback_context_)); |
| 161 |
| 162 delete this; |
| 163 } |
| 164 |
| 165 SkBitmap* NotificationPermissionInfoBarDelegate::GetIcon() const { |
| 166 return ResourceBundle::GetSharedInstance().GetBitmapNamed( |
| 167 IDR_PRODUCT_ICON_32); |
| 168 } |
| 169 |
| 170 InfoBarDelegate::Type |
| 171 NotificationPermissionInfoBarDelegate::GetInfoBarType() const { |
| 172 return PAGE_ACTION_TYPE; |
| 173 } |
| 174 |
| 175 string16 NotificationPermissionInfoBarDelegate::GetMessageText() const { |
| 176 return l10n_util::GetStringFUTF16(IDS_NOTIFICATION_PERMISSIONS, |
| 177 display_name_); |
| 178 } |
| 179 |
| 180 int NotificationPermissionInfoBarDelegate::GetButtons() const { |
| 181 return BUTTON_OK | BUTTON_CANCEL; |
| 182 } |
| 183 |
| 184 string16 NotificationPermissionInfoBarDelegate::GetButtonLabel( |
| 185 InfoBarButton button) const { |
| 186 return l10n_util::GetStringUTF16((button == BUTTON_OK) ? |
| 187 IDS_NOTIFICATION_PERMISSION_YES : IDS_NOTIFICATION_PERMISSION_NO); |
| 188 } |
| 189 |
| 190 bool NotificationPermissionInfoBarDelegate::Accept() { |
| 191 UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Allowed", 1); |
| 192 profile_->GetDesktopNotificationService()->GrantPermission(origin_); |
| 193 action_taken_ = true; |
| 194 return true; |
| 195 } |
| 196 |
| 197 bool NotificationPermissionInfoBarDelegate::Cancel() { |
| 198 UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Denied", 1); |
| 199 profile_->GetDesktopNotificationService()->DenyPermission(origin_); |
| 200 action_taken_ = true; |
| 201 return true; |
| 202 } |
| 203 |
| 204 |
| 205 // DesktopNotificationService ------------------------------------------------- |
| 206 |
46 // static | 207 // static |
47 string16 DesktopNotificationService::CreateDataUrl( | 208 string16 DesktopNotificationService::CreateDataUrl( |
48 const GURL& icon_url, const string16& title, const string16& body, | 209 const GURL& icon_url, const string16& title, const string16& body, |
49 WebTextDirection dir) { | 210 WebTextDirection dir) { |
50 int resource; | 211 int resource; |
51 std::vector<std::string> subst; | 212 std::vector<std::string> subst; |
52 if (icon_url.is_valid()) { | 213 if (icon_url.is_valid()) { |
53 resource = IDR_NOTIFICATION_ICON_HTML; | 214 resource = IDR_NOTIFICATION_ICON_HTML; |
54 subst.push_back(icon_url.spec()); | 215 subst.push_back(icon_url.spec()); |
55 subst.push_back(EscapeForHTML(UTF16ToUTF8(title))); | 216 subst.push_back(EscapeForHTML(UTF16ToUTF8(title))); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 if (template_html.empty()) { | 248 if (template_html.empty()) { |
88 NOTREACHED() << "unable to load template. ID: " << resource; | 249 NOTREACHED() << "unable to load template. ID: " << resource; |
89 return string16(); | 250 return string16(); |
90 } | 251 } |
91 | 252 |
92 std::string data = ReplaceStringPlaceholders(template_html, subst, NULL); | 253 std::string data = ReplaceStringPlaceholders(template_html, subst, NULL); |
93 return UTF8ToUTF16("data:text/html;charset=utf-8," + | 254 return UTF8ToUTF16("data:text/html;charset=utf-8," + |
94 EscapeQueryParamValue(data, false)); | 255 EscapeQueryParamValue(data, false)); |
95 } | 256 } |
96 | 257 |
97 // A task object which calls the renderer to inform the web page that the | |
98 // permission request has completed. | |
99 class NotificationPermissionCallbackTask : public Task { | |
100 public: | |
101 NotificationPermissionCallbackTask(int process_id, int route_id, | |
102 int request_id) | |
103 : process_id_(process_id), | |
104 route_id_(route_id), | |
105 request_id_(request_id) { | |
106 } | |
107 | |
108 virtual void Run() { | |
109 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
110 RenderViewHost* host = RenderViewHost::FromID(process_id_, route_id_); | |
111 if (host) | |
112 host->Send(new ViewMsg_PermissionRequestDone(route_id_, request_id_)); | |
113 } | |
114 | |
115 private: | |
116 int process_id_; | |
117 int route_id_; | |
118 int request_id_; | |
119 }; | |
120 | |
121 // The delegate for the infobar shown when an origin requests notification | |
122 // permissions. | |
123 class NotificationPermissionInfoBarDelegate : public ConfirmInfoBarDelegate { | |
124 public: | |
125 NotificationPermissionInfoBarDelegate(TabContents* contents, | |
126 const GURL& origin, | |
127 const string16& display_name, | |
128 int process_id, | |
129 int route_id, | |
130 int callback_context) | |
131 : ConfirmInfoBarDelegate(contents), | |
132 origin_(origin), | |
133 display_name_(display_name), | |
134 profile_(contents->profile()), | |
135 process_id_(process_id), | |
136 route_id_(route_id), | |
137 callback_context_(callback_context), | |
138 action_taken_(false) { | |
139 } | |
140 | |
141 // Overridden from ConfirmInfoBarDelegate: | |
142 virtual void InfoBarClosed() { | |
143 if (!action_taken_) | |
144 UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Ignored", 1); | |
145 | |
146 BrowserThread::PostTask( | |
147 BrowserThread::IO, FROM_HERE, | |
148 new NotificationPermissionCallbackTask( | |
149 process_id_, route_id_, callback_context_)); | |
150 | |
151 delete this; | |
152 } | |
153 | |
154 virtual string16 GetMessageText() const { | |
155 return l10n_util::GetStringFUTF16(IDS_NOTIFICATION_PERMISSIONS, | |
156 display_name_); | |
157 } | |
158 | |
159 virtual SkBitmap* GetIcon() const { | |
160 return ResourceBundle::GetSharedInstance().GetBitmapNamed( | |
161 IDR_PRODUCT_ICON_32); | |
162 } | |
163 | |
164 virtual int GetButtons() const { | |
165 return BUTTON_OK | BUTTON_CANCEL | BUTTON_OK_DEFAULT; | |
166 } | |
167 | |
168 virtual string16 GetButtonLabel(InfoBarButton button) const { | |
169 return button == BUTTON_OK ? | |
170 l10n_util::GetStringUTF16(IDS_NOTIFICATION_PERMISSION_YES) : | |
171 l10n_util::GetStringUTF16(IDS_NOTIFICATION_PERMISSION_NO); | |
172 } | |
173 | |
174 virtual bool Accept() { | |
175 UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Allowed", 1); | |
176 profile_->GetDesktopNotificationService()->GrantPermission(origin_); | |
177 action_taken_ = true; | |
178 return true; | |
179 } | |
180 | |
181 virtual bool Cancel() { | |
182 UMA_HISTOGRAM_COUNTS("NotificationPermissionRequest.Denied", 1); | |
183 profile_->GetDesktopNotificationService()->DenyPermission(origin_); | |
184 action_taken_ = true; | |
185 return true; | |
186 } | |
187 | |
188 // Overridden from InfoBarDelegate: | |
189 virtual Type GetInfoBarType() { return PAGE_ACTION_TYPE; } | |
190 | |
191 private: | |
192 // The origin we are asking for permissions on. | |
193 GURL origin_; | |
194 | |
195 // The display name for the origin to be displayed. Will be different from | |
196 // origin_ for extensions. | |
197 string16 display_name_; | |
198 | |
199 // The Profile that we restore sessions from. | |
200 Profile* profile_; | |
201 | |
202 // The callback information that tells us how to respond to javascript via | |
203 // the correct RenderView. | |
204 int process_id_; | |
205 int route_id_; | |
206 int callback_context_; | |
207 | |
208 // Whether the user clicked one of the buttons. | |
209 bool action_taken_; | |
210 | |
211 DISALLOW_COPY_AND_ASSIGN(NotificationPermissionInfoBarDelegate); | |
212 }; | |
213 | |
214 DesktopNotificationService::DesktopNotificationService(Profile* profile, | 258 DesktopNotificationService::DesktopNotificationService(Profile* profile, |
215 NotificationUIManager* ui_manager) | 259 NotificationUIManager* ui_manager) |
216 : profile_(profile), | 260 : profile_(profile), |
217 ui_manager_(ui_manager) { | 261 ui_manager_(ui_manager) { |
218 prefs_registrar_.Init(profile_->GetPrefs()); | 262 prefs_registrar_.Init(profile_->GetPrefs()); |
219 InitPrefs(); | 263 InitPrefs(); |
220 StartObserving(); | 264 StartObserving(); |
221 } | 265 } |
222 | 266 |
223 DesktopNotificationService::~DesktopNotificationService() { | 267 DesktopNotificationService::~DesktopNotificationService() { |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 } | 674 } |
631 return UTF8ToUTF16(origin.host()); | 675 return UTF8ToUTF16(origin.host()); |
632 } | 676 } |
633 | 677 |
634 void DesktopNotificationService::NotifySettingsChange() { | 678 void DesktopNotificationService::NotifySettingsChange() { |
635 NotificationService::current()->Notify( | 679 NotificationService::current()->Notify( |
636 NotificationType::DESKTOP_NOTIFICATION_SETTINGS_CHANGED, | 680 NotificationType::DESKTOP_NOTIFICATION_SETTINGS_CHANGED, |
637 Source<DesktopNotificationService>(this), | 681 Source<DesktopNotificationService>(this), |
638 NotificationService::NoDetails()); | 682 NotificationService::NoDetails()); |
639 } | 683 } |
OLD | NEW |