/* * Copyright (C) 2009 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "WebDesktopNotificationsDelegate.h" #include "WebSecurityOrigin.h" #include "WebView.h" #include <WebCore/BString.h> #include <WebCore/Document.h> #include <WebCore/KURL.h> #if ENABLE(NOTIFICATIONS) using namespace WebCore; class NotificationCOMWrapper : public IWebDesktopNotification { public: static NotificationCOMWrapper* create(Notification* inner) { return new NotificationCOMWrapper(inner); } // IUnknown virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); virtual ULONG STDMETHODCALLTYPE AddRef(); virtual ULONG STDMETHODCALLTYPE Release(); // IWebDesktopNotification HRESULT STDMETHODCALLTYPE isHTML(BOOL* result); HRESULT STDMETHODCALLTYPE contentsURL(BSTR* result); HRESULT STDMETHODCALLTYPE iconURL(BSTR* result); HRESULT STDMETHODCALLTYPE title(BSTR* result); HRESULT STDMETHODCALLTYPE text(BSTR* result); HRESULT STDMETHODCALLTYPE notifyDisplay(); HRESULT STDMETHODCALLTYPE notifyError(); HRESULT STDMETHODCALLTYPE notifyClose(BOOL xplicit); private: NotificationCOMWrapper(Notification* inner) : m_refCount(1), m_inner(inner) {} int m_refCount; Notification* m_inner; }; HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::QueryInterface(REFIID riid, void** ppvObject) { *ppvObject = 0; if (IsEqualGUID(riid, IID_IUnknown)) *ppvObject = static_cast<NotificationCOMWrapper*>(this); else if (IsEqualGUID(riid, IID_IWebDesktopNotification)) *ppvObject = static_cast<NotificationCOMWrapper*>(this); else return E_NOINTERFACE; AddRef(); return S_OK; } ULONG STDMETHODCALLTYPE NotificationCOMWrapper::AddRef() { return ++m_refCount; } ULONG STDMETHODCALLTYPE NotificationCOMWrapper::Release() { ULONG newRef = --m_refCount; if (!newRef) delete(this); return newRef; } HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::isHTML(BOOL* result) { *result = m_inner->isHTML(); return S_OK; } HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::contentsURL(BSTR* result) { *result = BString(m_inner->url()).release(); return S_OK; } HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::iconURL(BSTR* result) { *result = BString(m_inner->contents().icon()).release(); return S_OK; } HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::title(BSTR* result) { *result = BString(m_inner->contents().title()).release(); return S_OK; } HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::text(BSTR* result) { *result = BString(m_inner->contents().body()).release(); return S_OK; } HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::notifyDisplay() { m_inner->dispatchDisplayEvent(); return S_OK; } HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::notifyError() { m_inner->dispatchErrorEvent(); return S_OK; } HRESULT STDMETHODCALLTYPE NotificationCOMWrapper::notifyClose(BOOL xplicit) { m_inner->dispatchCloseEvent(); return S_OK; } WebDesktopNotificationsDelegate::WebDesktopNotificationsDelegate(WebView* webView) : m_webView(webView) { } bool WebDesktopNotificationsDelegate::show(Notification* object) { if (hasNotificationDelegate()) notificationDelegate()->showDesktopNotification(NotificationCOMWrapper::create(object)); return true; } void WebDesktopNotificationsDelegate::cancel(Notification* object) { if (hasNotificationDelegate()) notificationDelegate()->cancelDesktopNotification(NotificationCOMWrapper::create(object)); } void WebDesktopNotificationsDelegate::notificationObjectDestroyed(Notification* object) { if (hasNotificationDelegate()) notificationDelegate()->notificationDestroyed(NotificationCOMWrapper::create(object)); } void WebDesktopNotificationsDelegate::requestPermission(SecurityOrigin* origin, PassRefPtr<VoidCallback> callback) { BString org(origin->toString()); if (hasNotificationDelegate()) notificationDelegate()->requestNotificationPermission(org); } NotificationPresenter::Permission WebDesktopNotificationsDelegate::checkPermission(const KURL& url, Document*) { int out = 0; BString org(SecurityOrigin::create(url)->toString()); if (hasNotificationDelegate()) notificationDelegate()->checkNotificationPermission(org, &out); return (NotificationPresenter::Permission) out; } bool WebDesktopNotificationsDelegate::hasNotificationDelegate() { COMPtr<IWebUIDelegate> ui; m_webView->uiDelegate(&ui); COMPtr<IWebUIDelegate2> ui2; return SUCCEEDED(ui->QueryInterface(IID_IWebUIDelegate2, (void**) &ui2)); } COMPtr<IWebDesktopNotificationsDelegate> WebDesktopNotificationsDelegate::notificationDelegate() { COMPtr<IWebUIDelegate> ui; m_webView->uiDelegate(&ui); COMPtr<IWebUIDelegate2> ui2; COMPtr<IWebDesktopNotificationsDelegate> delegate; if (SUCCEEDED(ui->QueryInterface(IID_IWebUIDelegate2, (void**) &ui2))) ui2->desktopNotificationsDelegate(&delegate); return delegate; } #endif // ENABLE(NOTIFICATIONS)