/*
* 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)