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) || ENABLE(LEGACY_NOTIFICATIONS) 40 41using namespace WebCore; 42 43class NotificationCOMWrapper : public IWebDesktopNotification { 44public: 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 62private: 63 NotificationCOMWrapper(Notification* inner) : m_refCount(1), m_inner(inner) {} 64 65 int m_refCount; 66 Notification* m_inner; 67}; 68 69HRESULT 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 83ULONG STDMETHODCALLTYPE NotificationCOMWrapper::AddRef() 84{ 85 return ++m_refCount; 86} 87 88ULONG STDMETHODCALLTYPE NotificationCOMWrapper::Release() 89{ 90 ULONG newRef = --m_refCount; 91 if (!newRef) 92 delete(this); 93 return newRef; 94} 95 96HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::isHTML(BOOL* result) 97{ 98 *result = m_inner->isHTML(); 99 return S_OK; 100} 101 102HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::contentsURL(BSTR* result) 103{ 104 *result = BString(m_inner->url()).release(); 105 return S_OK; 106} 107 108HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::iconURL(BSTR* result) 109{ 110 *result = BString(m_inner->contents().icon()).release(); 111 return S_OK; 112} 113 114HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::title(BSTR* result) 115{ 116 *result = BString(m_inner->contents().title()).release(); 117 return S_OK; 118} 119 120HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::text(BSTR* result) 121{ 122 *result = BString(m_inner->contents().body()).release(); 123 return S_OK; 124} 125 126HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::notifyDisplay() 127{ 128 m_inner->dispatchDisplayEvent(); 129 return S_OK; 130} 131 132HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::notifyError() 133{ 134 m_inner->dispatchErrorEvent(); 135 return S_OK; 136} 137 138HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::notifyClose(BOOL xplicit) 139{ 140 m_inner->dispatchCloseEvent(); 141 return S_OK; 142} 143 144WebDesktopNotificationsDelegate::WebDesktopNotificationsDelegate(WebView* webView) 145 : m_webView(webView) 146{ 147} 148 149bool WebDesktopNotificationsDelegate::show(Notification* object) 150{ 151 if (hasNotificationDelegate()) 152 notificationDelegate()->showDesktopNotification(NotificationCOMWrapper::create(object)); 153 return true; 154} 155 156void WebDesktopNotificationsDelegate::cancel(Notification* object) 157{ 158 if (hasNotificationDelegate()) 159 notificationDelegate()->cancelDesktopNotification(NotificationCOMWrapper::create(object)); 160} 161 162void WebDesktopNotificationsDelegate::notificationObjectDestroyed(Notification* object) 163{ 164 if (hasNotificationDelegate()) 165 notificationDelegate()->notificationDestroyed(NotificationCOMWrapper::create(object)); 166} 167 168void WebDesktopNotificationsDelegate::notificationControllerDestroyed() 169{ 170} 171 172void WebDesktopNotificationsDelegate::requestPermission(SecurityOrigin* origin, PassRefPtr<VoidCallback> callback) 173{ 174 BString org(origin->toString()); 175 if (hasNotificationDelegate()) 176 notificationDelegate()->requestNotificationPermission(org); 177} 178 179void WebDesktopNotificationsDelegate::requestPermission(SecurityOrigin*, PassRefPtr<NotificationPermissionCallback>) 180{ 181} 182 183void WebDesktopNotificationsDelegate::cancelRequestsForPermission(ScriptExecutionContext* context) 184{ 185} 186 187NotificationClient::Permission WebDesktopNotificationsDelegate::checkPermission(const KURL& url) 188{ 189 int out = 0; 190 BString org(SecurityOrigin::create(url)->toString()); 191 if (hasNotificationDelegate()) 192 notificationDelegate()->checkNotificationPermission(org, &out); 193 return (NotificationClient::Permission) out; 194} 195 196bool WebDesktopNotificationsDelegate::hasNotificationDelegate() 197{ 198 COMPtr<IWebUIDelegate> ui; 199 m_webView->uiDelegate(&ui); 200 201 COMPtr<IWebUIDelegate2> ui2; 202 return SUCCEEDED(ui->QueryInterface(IID_IWebUIDelegate2, (void**) &ui2)); 203} 204 205COMPtr<IWebDesktopNotificationsDelegate> WebDesktopNotificationsDelegate::notificationDelegate() 206{ 207 COMPtr<IWebUIDelegate> ui; 208 m_webView->uiDelegate(&ui); 209 210 COMPtr<IWebUIDelegate2> ui2; 211 COMPtr<IWebDesktopNotificationsDelegate> delegate; 212 if (SUCCEEDED(ui->QueryInterface(IID_IWebUIDelegate2, (void**) &ui2))) 213 ui2->desktopNotificationsDelegate(&delegate); 214 215 return delegate; 216} 217 218#endif // ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS) 219