1 /*
2 * Copyright (C) 2009 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "config.h"
32 #include "WebDesktopNotificationsDelegate.h"
33 #include "WebSecurityOrigin.h"
34 #include "WebView.h"
35 #include <WebCore/BString.h>
36 #include <WebCore/Document.h>
37 #include <WebCore/KURL.h>
38
39 #if ENABLE(NOTIFICATIONS)
40
41 using namespace WebCore;
42
43 class NotificationCOMWrapper : public IWebDesktopNotification {
44 public:
create(Notification * inner)45 static NotificationCOMWrapper* create(Notification* inner) { return new NotificationCOMWrapper(inner); }
46
47 // IUnknown
48 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
49 virtual ULONG STDMETHODCALLTYPE AddRef();
50 virtual ULONG STDMETHODCALLTYPE Release();
51
52 // IWebDesktopNotification
53 HRESULT STDMETHODCALLTYPE isHTML(BOOL* result);
54 HRESULT STDMETHODCALLTYPE contentsURL(BSTR* result);
55 HRESULT STDMETHODCALLTYPE iconURL(BSTR* result);
56 HRESULT STDMETHODCALLTYPE title(BSTR* result);
57 HRESULT STDMETHODCALLTYPE text(BSTR* result);
58 HRESULT STDMETHODCALLTYPE notifyDisplay();
59 HRESULT STDMETHODCALLTYPE notifyError();
60 HRESULT STDMETHODCALLTYPE notifyClose(BOOL xplicit);
61
62 private:
NotificationCOMWrapper(Notification * inner)63 NotificationCOMWrapper(Notification* inner) : m_refCount(1), m_inner(inner) {}
64
65 int m_refCount;
66 Notification* m_inner;
67 };
68
QueryInterface(REFIID riid,void ** ppvObject)69 HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::QueryInterface(REFIID riid, void** ppvObject)
70 {
71 *ppvObject = 0;
72 if (IsEqualGUID(riid, IID_IUnknown))
73 *ppvObject = static_cast<NotificationCOMWrapper*>(this);
74 else if (IsEqualGUID(riid, IID_IWebDesktopNotification))
75 *ppvObject = static_cast<NotificationCOMWrapper*>(this);
76 else
77 return E_NOINTERFACE;
78
79 AddRef();
80 return S_OK;
81 }
82
AddRef()83 ULONG STDMETHODCALLTYPE NotificationCOMWrapper::AddRef()
84 {
85 return ++m_refCount;
86 }
87
Release()88 ULONG STDMETHODCALLTYPE NotificationCOMWrapper::Release()
89 {
90 ULONG newRef = --m_refCount;
91 if (!newRef)
92 delete(this);
93 return newRef;
94 }
95
isHTML(BOOL * result)96 HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::isHTML(BOOL* result)
97 {
98 *result = m_inner->isHTML();
99 return S_OK;
100 }
101
contentsURL(BSTR * result)102 HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::contentsURL(BSTR* result)
103 {
104 *result = BString(m_inner->url()).release();
105 return S_OK;
106 }
107
iconURL(BSTR * result)108 HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::iconURL(BSTR* result)
109 {
110 *result = BString(m_inner->contents().icon()).release();
111 return S_OK;
112 }
113
title(BSTR * result)114 HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::title(BSTR* result)
115 {
116 *result = BString(m_inner->contents().title()).release();
117 return S_OK;
118 }
119
text(BSTR * result)120 HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::text(BSTR* result)
121 {
122 *result = BString(m_inner->contents().body()).release();
123 return S_OK;
124 }
125
notifyDisplay()126 HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::notifyDisplay()
127 {
128 m_inner->dispatchDisplayEvent();
129 return S_OK;
130 }
131
notifyError()132 HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::notifyError()
133 {
134 m_inner->dispatchErrorEvent();
135 return S_OK;
136 }
137
notifyClose(BOOL xplicit)138 HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::notifyClose(BOOL xplicit)
139 {
140 m_inner->dispatchCloseEvent();
141 return S_OK;
142 }
143
WebDesktopNotificationsDelegate(WebView * webView)144 WebDesktopNotificationsDelegate::WebDesktopNotificationsDelegate(WebView* webView)
145 : m_webView(webView)
146 {
147 }
148
show(Notification * object)149 bool WebDesktopNotificationsDelegate::show(Notification* object)
150 {
151 if (hasNotificationDelegate())
152 notificationDelegate()->showDesktopNotification(NotificationCOMWrapper::create(object));
153 return true;
154 }
155
cancel(Notification * object)156 void WebDesktopNotificationsDelegate::cancel(Notification* object)
157 {
158 if (hasNotificationDelegate())
159 notificationDelegate()->cancelDesktopNotification(NotificationCOMWrapper::create(object));
160 }
161
notificationObjectDestroyed(Notification * object)162 void WebDesktopNotificationsDelegate::notificationObjectDestroyed(Notification* object)
163 {
164 if (hasNotificationDelegate())
165 notificationDelegate()->notificationDestroyed(NotificationCOMWrapper::create(object));
166 }
167
requestPermission(SecurityOrigin * origin,PassRefPtr<VoidCallback> callback)168 void WebDesktopNotificationsDelegate::requestPermission(SecurityOrigin* origin, PassRefPtr<VoidCallback> callback)
169 {
170 BString org(origin->toString());
171 if (hasNotificationDelegate())
172 notificationDelegate()->requestNotificationPermission(org);
173 }
174
checkPermission(const KURL & url,Document *)175 NotificationPresenter::Permission WebDesktopNotificationsDelegate::checkPermission(const KURL& url, Document*)
176 {
177 int out = 0;
178 BString org(SecurityOrigin::create(url)->toString());
179 if (hasNotificationDelegate())
180 notificationDelegate()->checkNotificationPermission(org, &out);
181 return (NotificationPresenter::Permission) out;
182 }
183
hasNotificationDelegate()184 bool WebDesktopNotificationsDelegate::hasNotificationDelegate()
185 {
186 COMPtr<IWebUIDelegate> ui;
187 m_webView->uiDelegate(&ui);
188
189 COMPtr<IWebUIDelegate2> ui2;
190 return SUCCEEDED(ui->QueryInterface(IID_IWebUIDelegate2, (void**) &ui2));
191 }
192
notificationDelegate()193 COMPtr<IWebDesktopNotificationsDelegate> WebDesktopNotificationsDelegate::notificationDelegate()
194 {
195 COMPtr<IWebUIDelegate> ui;
196 m_webView->uiDelegate(&ui);
197
198 COMPtr<IWebUIDelegate2> ui2;
199 COMPtr<IWebDesktopNotificationsDelegate> delegate;
200 if (SUCCEEDED(ui->QueryInterface(IID_IWebUIDelegate2, (void**) &ui2)))
201 ui2->desktopNotificationsDelegate(&delegate);
202
203 return delegate;
204 }
205
206 #endif // ENABLE(NOTIFICATIONS)
207