| /* |
| * 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 "WebDesktopNotificationsDelegate.h" |
| #include "WebSecurityOrigin.h" |
| #include "WebView.h" |
| #include <WebCore/BString.h> |
| #include <WebCore/Document.h> |
| #include <wtf/URL.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(_In_ REFIID riid, _COM_Outptr_ 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 NotificationCOMWrapper::QueryInterface(_In_ REFIID riid, _COM_Outptr_ void** ppvObject) |
| { |
| if (!ppvObject) |
| return E_POINTER; |
| *ppvObject = nullptr; |
| 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 NotificationCOMWrapper::AddRef() |
| { |
| return ++m_refCount; |
| } |
| |
| ULONG NotificationCOMWrapper::Release() |
| { |
| ULONG newRef = --m_refCount; |
| if (!newRef) |
| delete(this); |
| return newRef; |
| } |
| |
| HRESULT NotificationCOMWrapper::isHTML(BOOL* result) |
| { |
| *result = m_inner->isHTML(); |
| return S_OK; |
| } |
| |
| HRESULT NotificationCOMWrapper::contentsURL(BSTR* result) |
| { |
| *result = BString(m_inner->url()).release(); |
| return S_OK; |
| } |
| |
| HRESULT NotificationCOMWrapper::iconURL(BSTR* result) |
| { |
| *result = BString(m_inner->contents().icon()).release(); |
| return S_OK; |
| } |
| |
| HRESULT NotificationCOMWrapper::title(BSTR* result) |
| { |
| *result = BString(m_inner->contents().title()).release(); |
| return S_OK; |
| } |
| |
| HRESULT NotificationCOMWrapper::text(BSTR* result) |
| { |
| *result = BString(m_inner->contents().body()).release(); |
| return S_OK; |
| } |
| |
| HRESULT NotificationCOMWrapper::notifyDisplay() |
| { |
| m_inner->dispatchDisplayEvent(); |
| return S_OK; |
| } |
| |
| HRESULT NotificationCOMWrapper::notifyError() |
| { |
| m_inner->dispatchErrorEvent(); |
| return S_OK; |
| } |
| |
| HRESULT 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::notificationControllerDestroyed() |
| { |
| } |
| |
| void WebDesktopNotificationsDelegate::requestPermission(SecurityOrigin* origin, RefPtr<VoidCallback>&&) |
| { |
| BString org(origin->toString()); |
| if (hasNotificationDelegate()) |
| notificationDelegate()->requestNotificationPermission(org); |
| } |
| |
| void WebDesktopNotificationsDelegate::requestPermission(SecurityOrigin*, RefPtr<NotificationPermissionCallback>&&) |
| { |
| } |
| |
| void WebDesktopNotificationsDelegate::cancelRequestsForPermission(ScriptExecutionContext* context) |
| { |
| } |
| |
| bool hasPendingPermissionRequests(ScriptExecutionContext*) const |
| { |
| // We can safely return false here because our implementation for requestPermission() never calls |
| // the completion callback. |
| return false; |
| } |
| |
| NotificationClient::Permission WebDesktopNotificationsDelegate::checkPermission(const URL& url) |
| { |
| int out = 0; |
| BString org(SecurityOrigin::create(url)->toString()); |
| if (hasNotificationDelegate()) |
| notificationDelegate()->checkNotificationPermission(org, &out); |
| return (NotificationClient::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) |