diff options
Diffstat (limited to 'src/core')
99 files changed, 4908 insertions, 600 deletions
diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro new file mode 100644 index 000000000..d72b27229 --- /dev/null +++ b/src/core/api/core_api.pro @@ -0,0 +1,44 @@ +TARGET = qtwebenginecoreapi +DESTDIR = $$OUT_PWD/$$getConfigDir() + +TEMPLATE = lib + +CONFIG += staticlib c++11 +QT += network + +# Don't create .prl file for this intermediate library because +# their contents get used when linking against them, breaking +# "-Wl,-whole-archive -lqtwebenginecoreapi --Wl,-no-whole-archive" +CONFIG -= create_prl + +# Copy this logic from qt_module.prf so that the intermediate library can be +# created to the same rules as the final module linking in core_module.pro. +!host_build:if(win32|mac):!macx-xcode { + contains(QT_CONFIG, debug_and_release):CONFIG += debug_and_release + contains(QT_CONFIG, build_all):CONFIG += build_all +} + +DEFINES += \ + BUILDING_CHROMIUM \ + NOMINMAX + +CHROMIUM_SRC_DIR = $$QTWEBENGINE_ROOT/$$getChromiumSrcDir() +INCLUDEPATH += $$QTWEBENGINE_ROOT/src/core \ + $$CHROMIUM_SRC_DIR + +linux-g++*: QMAKE_CXXFLAGS += -Wno-unused-parameter + +HEADERS = \ + qwebenginecallback.h \ + qwebenginecallback_p.h \ + qtwebenginecoreglobal.h \ + qtwebenginecoreglobal_p.h \ + qwebenginecookiestoreclient.h \ + qwebenginecookiestoreclient_p.h \ + qwebengineurlrequestinterceptor.h \ + qwebengineurlrequestinfo.h \ + qwebengineurlrequestinfo_p.h + +SOURCES = \ + qwebenginecookiestoreclient.cpp \ + qwebengineurlrequestinfo.cpp diff --git a/src/core/api/qtwebenginecoreglobal.h b/src/core/api/qtwebenginecoreglobal.h new file mode 100644 index 000000000..16daaab7d --- /dev/null +++ b/src/core/api/qtwebenginecoreglobal.h @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTWEBENGINECOREGLOBAL_H +#define QTWEBENGINECOREGLOBAL_H + +#include <QtCore/qglobal.h> + +#if defined(BUILDING_CHROMIUM) +# define QWEBENGINE_EXPORT Q_DECL_EXPORT +#else +# define QWEBENGINE_EXPORT Q_DECL_IMPORT +#endif + +#define ASSERT_ENUMS_MATCH(A, B) Q_STATIC_ASSERT_X(static_cast<int>(A) == static_cast<int>(B), "The enum values must match"); + +#endif // QTWEBENGINECOREGLOBAL_H diff --git a/src/core/qtwebenginecoreglobal.h b/src/core/api/qtwebenginecoreglobal_p.h index d09497ce8..e93ca9c2c 100644 --- a/src/core/qtwebenginecoreglobal.h +++ b/src/core/api/qtwebenginecoreglobal_p.h @@ -34,10 +34,21 @@ ** ****************************************************************************/ -#ifndef QTWEBENGINECOREGLOBAL_H -#define QTWEBENGINECOREGLOBAL_H +#ifndef QTWEBENGINECOREGLOBAL_P_H +#define QTWEBENGINECOREGLOBAL_P_H -#include <QtCore/qglobal.h> +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qtwebenginecoreglobal.h" #ifdef QT_WEBENGINE_LOGGING #define QT_NOT_YET_IMPLEMENTED fprintf(stderr, "function %s not implemented! - %s:%d\n", __func__, __FILE__, __LINE__); @@ -47,16 +58,6 @@ #define QT_NOT_USED Q_UNREACHABLE(); // This will assert in debug. #endif -#ifndef QT_STATIC -# if defined(BUILDING_CHROMIUM) -# define QWEBENGINE_EXPORT Q_DECL_EXPORT -# else -# define QWEBENGINE_EXPORT Q_DECL_IMPORT -# endif -#else -# define QWEBENGINE_EXPORT -#endif - -#define ASSERT_ENUMS_MATCH(A, B) Q_STATIC_ASSERT_X(static_cast<int>(A) == static_cast<int>(B), "The enum values must match"); +#define QWEBENGINE_PRIVATE_EXPORT QWEBENGINE_EXPORT -#endif // QTWEBENGINECOREGLOBAL_H +#endif // QTWEBENGINECOREGLOBAL_P_H diff --git a/src/core/api/qwebenginecallback.h b/src/core/api/qwebenginecallback.h new file mode 100644 index 000000000..ddee20d06 --- /dev/null +++ b/src/core/api/qwebenginecallback.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWEBENGINECALLBACK_H +#define QWEBENGINECALLBACK_H + +#include "qtwebenginecoreglobal.h" + +#include <QtCore/qcompilerdetection.h> // Needed for Q_DECL_OVERRIDE +#include <QtCore/qshareddata.h> +#include <QtCore/qstring.h> +#include <QtCore/qvariant.h> + +namespace QtWebEngineCore { +class CallbackDirectory; +} + +QT_BEGIN_NAMESPACE + +namespace QtWebEnginePrivate { + +template <typename T> +class QWebEngineCallbackPrivateBase : public QSharedData { +public: + QWebEngineCallbackPrivateBase() {} + virtual ~QWebEngineCallbackPrivateBase() {} + virtual void operator()(T) = 0; +}; + +template <typename T, typename F> +class QWebEngineCallbackPrivate : public QWebEngineCallbackPrivateBase<T> { +public: + QWebEngineCallbackPrivate(F callable) + : m_callable(callable) + {} + virtual void operator()(T value) Q_DECL_OVERRIDE { m_callable(value); } +private: + F m_callable; +}; + +} // namespace QtWebEnginePrivate + +template <typename T> +class QWebEngineCallback { +public: + template <typename F> + QWebEngineCallback(F f) + : d(new QtWebEnginePrivate::QWebEngineCallbackPrivate<T, F>(f)) + { } + QWebEngineCallback() { } + operator bool() const { return d; } +private: + friend class QtWebEngineCore::CallbackDirectory; + QExplicitlySharedDataPointer<QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> > d; +}; + +QT_END_NAMESPACE + +#endif // QWEBENGINECALLBACK_H diff --git a/src/core/api/qwebenginecallback_p.h b/src/core/api/qwebenginecallback_p.h new file mode 100644 index 000000000..44d9ceb14 --- /dev/null +++ b/src/core/api/qwebenginecallback_p.h @@ -0,0 +1,226 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWEBENGINECALLBACK_P_H +#define QWEBENGINECALLBACK_P_H + +#include "qtwebenginecoreglobal_p.h" +#include "qwebenginecallback.h" + +#include <QByteArray> +#include <QHash> +#include <QSharedData> +#include <QString> +#include <QVariant> +#include <type_traits> + +#define FOR_EACH_TYPE(F) \ + F(bool) \ + F(int) \ + F(const QString &) \ + F(const QByteArray &) \ + F(const QVariant &) + +namespace QtWebEngineCore { + +class CallbackDirectory { + template<typename T> + void invokeInternal(quint64 callbackId, T result); + template<typename T> + void invokeEmptyInternal(QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> *callback); + +public: + ~CallbackDirectory() + { + // "Cancel" pending callbacks by calling them with an invalid value. + // This guarantees that each callback is called exactly once. + for (CallbackSharedDataPointerBase * const sharedPtrBase: m_callbackMap) { + Q_ASSERT(sharedPtrBase); + sharedPtrBase->invokeEmpty(); + delete sharedPtrBase; + } + } + + enum ReservedCallbackIds { + NoCallbackId = 0, + DeleteCookieCallbackId, + DeleteSessionCookiesCallbackId, + DeleteAllCookiesCallbackId, + GetAllCookiesCallbackId, + + // Place reserved id's before this. + ReservedCallbackIdsEnd + }; + + template<typename T> + void registerCallback(quint64 callbackId, const QWebEngineCallback<T> &callback); + + template<typename T> + void invokeEmpty(const QWebEngineCallback<T> &callback); + +#define DEFINE_INVOKE_FOR_TYPE(Type) \ + void invoke(quint64 callbackId, Type result) { \ + invokeInternal<Type>(callbackId, std::forward<Type>(result)); \ + } + FOR_EACH_TYPE(DEFINE_INVOKE_FOR_TYPE) +#undef DEFINE_INVOKE_FOR_TYPE + +private: + struct CallbackSharedDataPointerBase { + virtual ~CallbackSharedDataPointerBase() { } + virtual void invokeEmpty() = 0; + virtual void doRef() = 0; + virtual void doDeref() = 0; + virtual operator bool () const = 0; + }; + + template <typename T> + struct CallbackSharedDataPointer : public CallbackSharedDataPointerBase { + CallbackDirectory* parent; + QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> *callback; + + ~CallbackSharedDataPointer() { doDeref(); } + CallbackSharedDataPointer() : parent(0), callback(0) { } + CallbackSharedDataPointer(const CallbackSharedDataPointer<T> &other) + : parent(other.parent), callback(other.callback) { doRef(); } + CallbackSharedDataPointer(CallbackDirectory *p, QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> *c) + : parent(p), callback(c) { Q_ASSERT(callback); doRef(); } + + void invokeEmpty() override; + operator bool () const override { return callback; } + + private: + void doRef() override; + void doDeref() override; + }; + + QHash<quint64, CallbackSharedDataPointerBase*> m_callbackMap; +}; + +template<typename T> +inline +void CallbackDirectory::registerCallback(quint64 callbackId, const QWebEngineCallback<T> &callback) +{ + if (!callback.d) + return; + m_callbackMap.insert(callbackId, new CallbackSharedDataPointer<T>(this, callback.d.data())); +} + +template<typename T> +inline +void CallbackDirectory::invokeInternal(quint64 callbackId, T result) +{ + CallbackSharedDataPointerBase * const sharedPtrBase = m_callbackMap.take(callbackId); + if (!sharedPtrBase) + return; + + auto ptr = static_cast<CallbackSharedDataPointer<T> *>(sharedPtrBase); + Q_ASSERT(ptr); + (*ptr->callback)(std::forward<T>(result)); + delete ptr; +} + +template<typename T> +inline +void CallbackDirectory::invokeEmptyInternal(QtWebEnginePrivate::QWebEngineCallbackPrivateBase<T> *callback) +{ + Q_ASSERT(callback); + using NoRefT = typename std::remove_reference<T>::type; + using NoConstNoRefT = typename std::remove_const<NoRefT>::type; + NoConstNoRefT t; + (*callback)(t); +} + +template<> +inline +void CallbackDirectory::invokeEmptyInternal(QtWebEnginePrivate::QWebEngineCallbackPrivateBase<bool> *callback) +{ + Q_ASSERT(callback); + (*callback)(false); +} + +template<> +inline +void CallbackDirectory::invokeEmptyInternal(QtWebEnginePrivate::QWebEngineCallbackPrivateBase<int> *callback) +{ + Q_ASSERT(callback); + (*callback)(0); +} + +template<typename T> +inline +void CallbackDirectory::invokeEmpty(const QWebEngineCallback<T> &callback) +{ + if (!callback.d) + return; + + invokeEmptyInternal(callback.d.data()); +} + +template <typename T> +inline +void CallbackDirectory::CallbackSharedDataPointer<T>::doRef() +{ + if (!callback) + return; + + callback->ref.ref(); +} + +template <typename T> +inline +void CallbackDirectory::CallbackSharedDataPointer<T>::doDeref() +{ + if (!callback) + return; + if (!callback->ref.deref()) + delete callback; +} + +template <typename T> +inline +void CallbackDirectory::CallbackSharedDataPointer<T>::invokeEmpty() +{ + if (!callback) + return; + + Q_ASSERT(parent); + parent->invokeEmptyInternal(callback); +} + +} // namespace QtWebEngineCore + +#endif // QWEBENGINECALLBACK_P_H diff --git a/src/core/api/qwebenginecookiestoreclient.cpp b/src/core/api/qwebenginecookiestoreclient.cpp new file mode 100644 index 000000000..f4770927e --- /dev/null +++ b/src/core/api/qwebenginecookiestoreclient.cpp @@ -0,0 +1,246 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwebenginecookiestoreclient.h" +#include "qwebenginecookiestoreclient_p.h" + +#include <QByteArray> +#include <QUrl> + +QT_BEGIN_NAMESPACE + +using namespace QtWebEngineCore; + +QWebEngineCookieStoreClientPrivate::QWebEngineCookieStoreClientPrivate(QWebEngineCookieStoreClient* q) + : m_nextCallbackId(CallbackDirectory::ReservedCallbackIdsEnd) + , m_deleteSessionCookiesPending(false) + , m_deleteAllCookiesPending(false) + , m_getAllCookiesPending(false) + , delegate(0) + , q_ptr(q) +{ +} + +QWebEngineCookieStoreClientPrivate::~QWebEngineCookieStoreClientPrivate() +{ + +} + +void QWebEngineCookieStoreClientPrivate::processPendingUserCookies() +{ + Q_ASSERT(delegate); + Q_ASSERT(delegate->hasCookieMonster()); + + if (m_getAllCookiesPending) { + m_getAllCookiesPending = false; + delegate->getAllCookies(CallbackDirectory::GetAllCookiesCallbackId); + } + + if (m_deleteAllCookiesPending) { + m_deleteAllCookiesPending = false; + delegate->deleteAllCookies(CallbackDirectory::DeleteAllCookiesCallbackId); + } + + if (m_deleteSessionCookiesPending) { + m_deleteSessionCookiesPending = false; + delegate->deleteSessionCookies(CallbackDirectory::DeleteSessionCookiesCallbackId); + } + + if (m_pendingUserCookies.isEmpty()) + return; + + Q_FOREACH (const auto &cookieData, m_pendingUserCookies) { + if (cookieData.callbackId == CallbackDirectory::DeleteCookieCallbackId) + delegate->deleteCookie(cookieData.cookie, cookieData.origin); + else + delegate->setCookie(cookieData.callbackId, cookieData.cookie, cookieData.origin); + } + + m_pendingUserCookies.clear(); +} + +void QWebEngineCookieStoreClientPrivate::setCookie(const QWebEngineCallback<bool> &callback, const QNetworkCookie &cookie, const QUrl &origin) +{ + const quint64 currentCallbackId = callback ? m_nextCallbackId++ : static_cast<quint64>(CallbackDirectory::NoCallbackId); + + if (currentCallbackId != CallbackDirectory::NoCallbackId) + callbackDirectory.registerCallback(currentCallbackId, callback); + + if (!delegate || !delegate->hasCookieMonster()) { + m_pendingUserCookies.append(CookieData{ currentCallbackId, cookie, origin }); + return; + } + + delegate->setCookie(currentCallbackId, cookie, origin); +} + +void QWebEngineCookieStoreClientPrivate::deleteCookie(const QNetworkCookie &cookie, const QUrl &url) +{ + if (!delegate || !delegate->hasCookieMonster()) { + m_pendingUserCookies.append(CookieData{ CallbackDirectory::DeleteCookieCallbackId, cookie, url }); + return; + } + + delegate->deleteCookie(cookie, url); +} + +void QWebEngineCookieStoreClientPrivate::deleteSessionCookies() +{ + if (!delegate || !delegate->hasCookieMonster()) { + m_deleteSessionCookiesPending = true; + return; + } + + delegate->deleteSessionCookies(CallbackDirectory::DeleteSessionCookiesCallbackId); +} + +void QWebEngineCookieStoreClientPrivate::deleteAllCookies() +{ + if (!delegate || !delegate->hasCookieMonster()) { + m_deleteAllCookiesPending = true; + m_deleteSessionCookiesPending = false; + return; + } + + delegate->deleteAllCookies(CallbackDirectory::DeleteAllCookiesCallbackId); +} + +void QWebEngineCookieStoreClientPrivate::getAllCookies() +{ + if (!delegate || !delegate->hasCookieMonster()) { + m_getAllCookiesPending = true; + return; + } + + delegate->getAllCookies(CallbackDirectory::GetAllCookiesCallbackId); +} + +void QWebEngineCookieStoreClientPrivate::onGetAllCallbackResult(qint64 callbackId, const QByteArray &cookieList) +{ + callbackDirectory.invoke(callbackId, cookieList); +} +void QWebEngineCookieStoreClientPrivate::onSetCallbackResult(qint64 callbackId, bool success) +{ + callbackDirectory.invoke(callbackId, success); +} + +void QWebEngineCookieStoreClientPrivate::onDeleteCallbackResult(qint64 callbackId, int numCookies) +{ + callbackDirectory.invoke(callbackId, numCookies); +} + +void QWebEngineCookieStoreClientPrivate::onCookieChanged(const QNetworkCookie &cookie, bool removed) +{ + Q_Q(QWebEngineCookieStoreClient); + if (removed) + Q_EMIT q->cookieRemoved(cookie); + else + Q_EMIT q->cookieAdded(cookie); +} + +QWebEngineCookieStoreClient::QWebEngineCookieStoreClient(QObject *parent) + : QObject(parent) + , d_ptr(new QWebEngineCookieStoreClientPrivate(this)) +{ + +} + +QWebEngineCookieStoreClient::~QWebEngineCookieStoreClient() +{ + +} + +void QWebEngineCookieStoreClient::setCookieWithCallback(const QNetworkCookie &cookie, const QWebEngineCallback<bool> &resultCallback, const QUrl &origin) +{ + Q_D(QWebEngineCookieStoreClient); + d->setCookie(resultCallback, cookie, origin); +} + +void QWebEngineCookieStoreClient::setCookie(const QNetworkCookie &cookie, const QUrl &origin) +{ + setCookieWithCallback(cookie, QWebEngineCallback<bool>(), origin); +} + +void QWebEngineCookieStoreClient::deleteCookie(const QNetworkCookie &cookie, const QUrl &origin) +{ + Q_D(QWebEngineCookieStoreClient); + d->deleteCookie(cookie, origin); +} + +void QWebEngineCookieStoreClient::getAllCookies(const QWebEngineCallback<const QByteArray&> &resultCallback) +{ + Q_D(QWebEngineCookieStoreClient); + if (d->m_getAllCookiesPending) { + d->callbackDirectory.invokeEmpty(resultCallback); + return; + } + d->callbackDirectory.registerCallback(CallbackDirectory::GetAllCookiesCallbackId, resultCallback); + d->getAllCookies(); +} + +void QWebEngineCookieStoreClient::deleteSessionCookiesWithCallback(const QWebEngineCallback<int> &resultCallback) +{ + Q_D(QWebEngineCookieStoreClient); + if (d->m_deleteAllCookiesPending || d->m_deleteSessionCookiesPending) { + d->callbackDirectory.invokeEmpty(resultCallback); + return; + } + d->callbackDirectory.registerCallback(CallbackDirectory::DeleteSessionCookiesCallbackId, resultCallback); + d->deleteSessionCookies(); +} + +void QWebEngineCookieStoreClient::deleteAllCookiesWithCallback(const QWebEngineCallback<int> &resultCallback) +{ + Q_D(QWebEngineCookieStoreClient); + if (d->m_deleteAllCookiesPending) { + d->callbackDirectory.invokeEmpty(resultCallback); + return; + } + d->callbackDirectory.registerCallback(CallbackDirectory::DeleteAllCookiesCallbackId, resultCallback); + d->deleteAllCookies(); +} + +void QWebEngineCookieStoreClient::deleteSessionCookies() +{ + deleteSessionCookiesWithCallback(QWebEngineCallback<int>()); +} + +void QWebEngineCookieStoreClient::deleteAllCookies() +{ + deleteAllCookiesWithCallback(QWebEngineCallback<int>()); +} + +QT_END_NAMESPACE diff --git a/src/core/api/qwebenginecookiestoreclient.h b/src/core/api/qwebenginecookiestoreclient.h new file mode 100644 index 000000000..929584c86 --- /dev/null +++ b/src/core/api/qwebenginecookiestoreclient.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWEBENGINECOOKIESTORECLIENT_H +#define QWEBENGINECOOKIESTORECLIENT_H + +#include "qtwebenginecoreglobal.h" +#include "qwebenginecallback.h" + +#include <QtCore/qobject.h> +#include <QtCore/qscopedpointer.h> +#include <QtCore/qurl.h> +#include <QtNetwork/qnetworkcookie.h> + +namespace QtWebEngineCore { +class CookieMonsterDelegateQt; +} + +QT_BEGIN_NAMESPACE + +class QWebEngineCookieStoreClientPrivate; +class QWEBENGINE_EXPORT QWebEngineCookieStoreClient : public QObject { + Q_OBJECT +public: + explicit QWebEngineCookieStoreClient(QObject *parent = 0); + virtual ~QWebEngineCookieStoreClient(); + +#ifdef Q_QDOC + void setCookieWithCallback(const QNetworkCookie &cookie, FunctorOrLambda resultCallback, const QUrl &origin = QUrl()); + void deleteSessionCookiesWithCallback(FunctorOrLambda resultCallback); + void deleteAllCookiesWithCallback(FunctorOrLambda resultCallback); + void getAllCookies(FunctorOrLambda resultCallback); +#else + void setCookieWithCallback(const QNetworkCookie &cookie, const QWebEngineCallback<bool> &resultCallback, const QUrl &origin = QUrl()); + void deleteSessionCookiesWithCallback(const QWebEngineCallback<int> &resultCallback); + void deleteAllCookiesWithCallback(const QWebEngineCallback<int> &resultCallback); + void getAllCookies(const QWebEngineCallback<const QByteArray&> &resultCallback); +#endif + void setCookie(const QNetworkCookie &cookie, const QUrl &origin = QUrl()); + void deleteCookie(const QNetworkCookie &cookie, const QUrl &origin = QUrl()); + void deleteSessionCookies(); + void deleteAllCookies(); + +Q_SIGNALS: + void cookieAdded(const QNetworkCookie &cookie); + void cookieRemoved(const QNetworkCookie &cookie); + +private: + friend class QtWebEngineCore::CookieMonsterDelegateQt; + + Q_DECLARE_PRIVATE(QWebEngineCookieStoreClient) + QScopedPointer<QWebEngineCookieStoreClientPrivate> d_ptr; +}; + +QT_END_NAMESPACE + +#endif // QWEBENGINECOOKIESTORECLIENT_H diff --git a/src/core/api/qwebenginecookiestoreclient_p.h b/src/core/api/qwebenginecookiestoreclient_p.h new file mode 100644 index 000000000..ba7914d94 --- /dev/null +++ b/src/core/api/qwebenginecookiestoreclient_p.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWEBENGINECOOKIESTORECLIENT_P_H +#define QWEBENGINECOOKIESTORECLIENT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qtwebenginecoreglobal_p.h" + +#include "cookie_monster_delegate_qt.h" +#include "qwebenginecallback_p.h" +#include "qwebenginecookiestoreclient.h" + +#include <QList> +#include <QMap> +#include <QNetworkCookie> +#include <QUrl> + +QT_BEGIN_NAMESPACE + +class QWEBENGINE_PRIVATE_EXPORT QWebEngineCookieStoreClientPrivate { + struct CookieData { + quint64 callbackId; + QNetworkCookie cookie; + QUrl origin; + }; + +public: + Q_DECLARE_PUBLIC(QWebEngineCookieStoreClient) + QtWebEngineCore::CallbackDirectory callbackDirectory; + QList<CookieData> m_pendingUserCookies; + quint64 m_nextCallbackId; + bool m_deleteSessionCookiesPending; + bool m_deleteAllCookiesPending; + bool m_getAllCookiesPending; + + QtWebEngineCore::CookieMonsterDelegateQt *delegate; + QWebEngineCookieStoreClient *q_ptr; + + QWebEngineCookieStoreClientPrivate(QWebEngineCookieStoreClient *q); + ~QWebEngineCookieStoreClientPrivate(); + + void processPendingUserCookies(); + void setCookie(const QWebEngineCallback<bool> &callback, const QNetworkCookie &cookie, const QUrl &origin); + void deleteCookie(const QNetworkCookie &cookie, const QUrl &url); + void deleteSessionCookies(); + void deleteAllCookies(); + void getAllCookies(); + + void onGetAllCallbackResult(qint64 callbackId, const QByteArray &cookieList); + void onSetCallbackResult(qint64 callbackId, bool success); + void onDeleteCallbackResult(qint64 callbackId, int numCookies); + void onCookieChanged(const QNetworkCookie &cookie, bool removed); +}; + +QT_END_NAMESPACE + +#endif // QWEBENGINECOOKIESTORECLIENT_P_H diff --git a/src/core/api/qwebengineurlrequestinfo.cpp b/src/core/api/qwebengineurlrequestinfo.cpp new file mode 100644 index 000000000..e97b0c7b9 --- /dev/null +++ b/src/core/api/qwebengineurlrequestinfo.cpp @@ -0,0 +1,133 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwebengineurlrequestinfo.h" +#include "qwebengineurlrequestinfo_p.h" + +#include "content/public/common/resource_type.h" + +#include "web_contents_adapter_client.h" + +QT_BEGIN_NAMESPACE + +ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeMainFrame, content::RESOURCE_TYPE_MAIN_FRAME) +ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeSubFrame, content::RESOURCE_TYPE_SUB_FRAME) +ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeStylesheet, content::RESOURCE_TYPE_STYLESHEET) +ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeScript, content::RESOURCE_TYPE_SCRIPT) +ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeImage, content::RESOURCE_TYPE_IMAGE) +ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeFontResource, content::RESOURCE_TYPE_FONT_RESOURCE) +ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeSubResource, content::RESOURCE_TYPE_SUB_RESOURCE) +ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeObject, content::RESOURCE_TYPE_OBJECT) +ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeMedia, content::RESOURCE_TYPE_MEDIA) +ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeWorker, content::RESOURCE_TYPE_WORKER) +ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeSharedWorker, content::RESOURCE_TYPE_SHARED_WORKER) +ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypePrefetch, content::RESOURCE_TYPE_PREFETCH) +ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeFavicon, content::RESOURCE_TYPE_FAVICON) +ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeXhr, content::RESOURCE_TYPE_XHR) +ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypePing, content::RESOURCE_TYPE_PING) +ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeServiceWorker, content::RESOURCE_TYPE_SERVICE_WORKER) +ASSERT_ENUMS_MATCH(QWebEngineUrlRequestInfo::ResourceTypeUnknown, content::RESOURCE_TYPE_LAST_TYPE) + +ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::LinkNavigation, QWebEngineUrlRequestInfo::NavigationTypeLink) +ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::TypedNavigation, QWebEngineUrlRequestInfo::NavigationTypeTyped) +ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::FormSubmittedNavigation, QWebEngineUrlRequestInfo::NavigationTypeFormSubmitted) +ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::BackForwardNavigation, QWebEngineUrlRequestInfo::NavigationTypeBackForward) +ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::ReloadNavigation, QWebEngineUrlRequestInfo::NavigationTypeReload) +ASSERT_ENUMS_MATCH(QtWebEngineCore::WebContentsAdapterClient::OtherNavigation, QWebEngineUrlRequestInfo::NavigationTypeOther) + +QWebEngineUrlRequestInfoPrivate::QWebEngineUrlRequestInfoPrivate(QWebEngineUrlRequestInfo::ResourceType resource, QWebEngineUrlRequestInfo::NavigationType navigation, const QUrl &u, const QByteArray &m) + : resourceType(resource) + , navigationType(navigation) + , shouldBlockRequest(false) + , url(u) + , method(m) +{ +} + +QWebEngineUrlRequestInfo::~QWebEngineUrlRequestInfo() +{ + +} + +QWebEngineUrlRequestInfo::QWebEngineUrlRequestInfo(QWebEngineUrlRequestInfoPrivate *p) + : d_ptr(p) +{ + d_ptr->q_ptr = this; +} + +QWebEngineUrlRequestInfo::ResourceType QWebEngineUrlRequestInfo::resourceType() const +{ + Q_D(const QWebEngineUrlRequestInfo); + return d->resourceType; +} + +QWebEngineUrlRequestInfo::NavigationType QWebEngineUrlRequestInfo::navigationType() const +{ + Q_D(const QWebEngineUrlRequestInfo); + return d->navigationType; +} + +const QUrl &QWebEngineUrlRequestInfo::url() const +{ + Q_D(const QWebEngineUrlRequestInfo); + return d->url; +} + +const QByteArray &QWebEngineUrlRequestInfo::method() const +{ + Q_D(const QWebEngineUrlRequestInfo); + return d->method; +} + +void QWebEngineUrlRequestInfo::redirectTo(const QUrl &url) +{ + Q_D(QWebEngineUrlRequestInfo); + d->url = url; +} + +void QWebEngineUrlRequestInfo::blockRequest(bool shouldBlock) +{ + Q_D(QWebEngineUrlRequestInfo); + d->shouldBlockRequest = shouldBlock; +} + +void QWebEngineUrlRequestInfo::setExtraHeader(const QByteArray &name, const QByteArray &value) +{ + Q_D(QWebEngineUrlRequestInfo); + d->extraHeaders.insert(name, value); +} + +QT_END_NAMESPACE diff --git a/src/core/api/qwebengineurlrequestinfo.h b/src/core/api/qwebengineurlrequestinfo.h new file mode 100644 index 000000000..dd1e57ebd --- /dev/null +++ b/src/core/api/qwebengineurlrequestinfo.h @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWEBENGINEURLREQUESTINFO_H +#define QWEBENGINEURLREQUESTINFO_H + +#include "qtwebenginecoreglobal.h" + +#include <QtCore/qscopedpointer.h> +#include <QtCore/qurl.h> + +namespace QtWebEngineCore { +class NetworkDelegateQt; +} + +QT_BEGIN_NAMESPACE + +class QWebEngineUrlRequestInfoPrivate; + +class QWEBENGINE_EXPORT QWebEngineUrlRequestInfo { +public: + enum ResourceType { + ResourceTypeMainFrame = 0, // top level page + ResourceTypeSubFrame, // frame or iframe + ResourceTypeStylesheet, // a CSS stylesheet + ResourceTypeScript, // an external script + ResourceTypeImage, // an image (jpg/gif/png/etc) + ResourceTypeFontResource, // a font + ResourceTypeSubResource, // an "other" subresource. + ResourceTypeObject, // an object (or embed) tag for a plugin, + // or a resource that a plugin requested. + ResourceTypeMedia, // a media resource. + ResourceTypeWorker, // the main resource of a dedicated worker. + ResourceTypeSharedWorker, // the main resource of a shared worker. + ResourceTypePrefetch, // an explicitly requested prefetch + ResourceTypeFavicon, // a favicon + ResourceTypeXhr, // a XMLHttpRequest + ResourceTypePing, // a ping request for <a ping> + ResourceTypeServiceWorker, // the main resource of a service worker. + ResourceTypeUnknown + }; + + enum NavigationType { + NavigationTypeLink, + NavigationTypeTyped, + NavigationTypeFormSubmitted, + NavigationTypeBackForward, + NavigationTypeReload, + NavigationTypeOther + }; + + ResourceType resourceType() const; + NavigationType navigationType() const; + + const QUrl &url() const; + const QByteArray &method() const; + + void blockRequest(bool shouldBlock); + void redirectTo(const QUrl &url); + void setExtraHeader(const QByteArray &name, const QByteArray &value); + +private: + friend class QtWebEngineCore::NetworkDelegateQt; + Q_DISABLE_COPY(QWebEngineUrlRequestInfo) + Q_DECLARE_PRIVATE(QWebEngineUrlRequestInfo) + + QWebEngineUrlRequestInfo(QWebEngineUrlRequestInfoPrivate *p); + ~QWebEngineUrlRequestInfo(); + QScopedPointer<QWebEngineUrlRequestInfoPrivate> d_ptr; +}; + +QT_END_NAMESPACE + +#endif // QWEBENGINEURLREQUESTINFO_H diff --git a/src/core/api/qwebengineurlrequestinfo_p.h b/src/core/api/qwebengineurlrequestinfo_p.h new file mode 100644 index 000000000..b6a304a03 --- /dev/null +++ b/src/core/api/qwebengineurlrequestinfo_p.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWEBENGINEURLREQUESTINFO_P_H +#define QWEBENGINEURLREQUESTINFO_P_H + +#include "qtwebenginecoreglobal_p.h" + +#include "qwebengineurlrequestinfo.h" + +#include <QByteArray> +#include <QHash> +#include <QUrl> + +namespace net { +class URLRequest; +} + +QT_BEGIN_NAMESPACE + +class QWebEngineUrlRequestInfoPrivate +{ + Q_DECLARE_PUBLIC(QWebEngineUrlRequestInfo) +public: + QWebEngineUrlRequestInfoPrivate(QWebEngineUrlRequestInfo::ResourceType resource + , QWebEngineUrlRequestInfo::NavigationType navigation + , const QUrl &u + , const QByteArray &m); + + QWebEngineUrlRequestInfo::ResourceType resourceType; + QWebEngineUrlRequestInfo::NavigationType navigationType; + bool shouldBlockRequest; + + QUrl url; + const QByteArray method; + QHash<QByteArray, QByteArray> extraHeaders; + + QWebEngineUrlRequestInfo *q_ptr; +}; + +QT_END_NAMESPACE + +#endif // QWEBENGINEURLREQUESTINFO_P_H diff --git a/src/core/api/qwebengineurlrequestinterceptor.h b/src/core/api/qwebengineurlrequestinterceptor.h new file mode 100644 index 000000000..3eac74bb6 --- /dev/null +++ b/src/core/api/qwebengineurlrequestinterceptor.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWEBENINGEURLREQUESTINTERCEPTOR_H +#define QWEBENINGEURLREQUESTINTERCEPTOR_H + +#include "qtwebenginecoreglobal.h" +#include "qwebengineurlrequestinfo.h" + +#include <QtCore/qbytearray.h> +#include <QtCore/qhash.h> +#include <QtCore/qobject.h> +#include <QtCore/qurl.h> + +QT_BEGIN_NAMESPACE + +class QWEBENGINE_EXPORT QWebEngineUrlRequestInterceptor : public QObject +{ + Q_OBJECT +public: + explicit QWebEngineUrlRequestInterceptor(QObject *p = 0) + : QObject (p) + { + } + virtual ~QWebEngineUrlRequestInterceptor() + { + } + + virtual bool interceptRequest(QWebEngineUrlRequestInfo &info) = 0; +}; + +QT_END_NAMESPACE + +#endif // QWEBENINGEURLREQUESTINTERCEPTOR_H diff --git a/src/core/browser_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp index 7cd5ac21f..9d4fdfe00 100644 --- a/src/core/browser_accessibility_qt.cpp +++ b/src/core/browser_accessibility_qt.cpp @@ -46,7 +46,7 @@ #include "ui/accessibility/ax_node_data.h" #include "browser_accessibility_manager_qt.h" -#include "qtwebenginecoreglobal.h" +#include "qtwebenginecoreglobal_p.h" #include "type_conversion.h" using namespace blink; @@ -59,82 +59,6 @@ BrowserAccessibilityQt::BrowserAccessibilityQt() QAccessible::registerAccessibleInterface(this); } -// This function is taken from chromium/content/browser/accessibility/browser_accessibility_win.cc -// see also http://www.w3.org/TR/html-aapi -void BrowserAccessibilityQt::OnDataChanged() -{ - BrowserAccessibility::OnDataChanged(); - - // The calculation of the accessible name of an element has been - // standardized in the HTML to Platform Accessibility APIs Implementation - // Guide (http://www.w3.org/TR/html-aapi/). In order to return the - // appropriate accessible name on Windows, we need to apply some logic - // to the fields we get from WebKit. - // - // TODO(dmazzoni): move most of this logic into WebKit. - // - // WebKit gives us: - // - // name: the default name, e.g. inner text - // title ui element: a reference to a <label> element on the same - // page that labels this node. - // description: accessible labels that override the default name: - // aria-label or aria-labelledby or aria-describedby - // help: the value of the "title" attribute - // - // On Windows, the logic we apply lets some fields take precedence and - // always returns the primary name in "name" and the secondary name, - // if any, in "description". - - int title_elem_id = GetIntAttribute( - ui::AX_ATTR_TITLE_UI_ELEMENT); - std::string help = GetStringAttribute(ui::AX_ATTR_HELP); - std::string description = GetStringAttribute( - ui::AX_ATTR_DESCRIPTION); - - // WebKit annoyingly puts the title in the description if there's no other - // description, which just confuses the rest of the logic. Put it back. - // Now "help" is always the value of the "title" attribute, if present. - std::string title_attr; - if (GetHtmlAttribute("title", &title_attr) && - description == title_attr && - help.empty()) { - help = description; - description.clear(); - } - - // Now implement the main logic: the descripion should become the name if - // it's nonempty, and the help should become the description if - // there's no description - or the name if there's no name or description. - if (!description.empty()) { - set_name(description); - description.clear(); - } - if (!help.empty() && description.empty()) { - description = help; - help.clear(); - } - if (!description.empty() && name().empty() && !title_elem_id) { - set_name(description); - description.clear(); - } - - // If it's a text field, also consider the placeholder. - std::string placeholder; - if (GetRole() == ui::AX_ROLE_TEXT_FIELD && - HasState(ui::AX_STATE_FOCUSABLE) && - GetHtmlAttribute("placeholder", &placeholder)) { - if (name().empty() && !title_elem_id) { - set_name(placeholder); - } else if (description.empty()) { - description = placeholder; - } - } - - SetStringAttribute(ui::AX_ATTR_DESCRIPTION, description); - SetStringAttribute(ui::AX_ATTR_HELP, help); -} - bool BrowserAccessibilityQt::isValid() const { return true; @@ -227,7 +151,7 @@ QString BrowserAccessibilityQt::text(QAccessible::Text t) const { switch (t) { case QAccessible::Name: - return toQt(name()); + return toQt(GetStringAttribute(ui::AX_ATTR_NAME)); case QAccessible::Description: return toQt(GetStringAttribute(ui::AX_ATTR_DESCRIPTION)); case QAccessible::Help: @@ -277,10 +201,10 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::Document; // returning Application here makes Qt return the top level app object case ui::AX_ROLE_ARTICLE: return QAccessible::Section; - case ui::AX_ROLE_BROWSER: - return QAccessible::Document; // FIXME case ui::AX_ROLE_BANNER: return QAccessible::Section; + case ui::AX_ROLE_BLOCKQUOTE: + return QAccessible::Section; case ui::AX_ROLE_BUSY_INDICATOR: return QAccessible::Animation; // FIXME case ui::AX_ROLE_BUTTON: @@ -325,10 +249,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::Section; case ui::AX_ROLE_DOCUMENT: return QAccessible::Document; - case ui::AX_ROLE_DRAWER: - return QAccessible::Client; // FIXME - case ui::AX_ROLE_EDITABLE_TEXT: - return QAccessible::EditableText; case ui::AX_ROLE_EMBEDDED_OBJECT: return QAccessible::Grouping; // FIXME case ui::AX_ROLE_FOOTER: @@ -339,14 +259,8 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::Table; case ui::AX_ROLE_GROUP: return QAccessible::Grouping; - case ui::AX_ROLE_GROW_AREA: - return QAccessible::Grip; case ui::AX_ROLE_HEADING: return QAccessible::Heading; - case ui::AX_ROLE_HELP_TAG: - return QAccessible::HelpBalloon; // FIXME - case ui::AX_ROLE_HORIZONTAL_RULE: - return QAccessible::Separator; case ui::AX_ROLE_IFRAME: return QAccessible::Grouping; case ui::AX_ROLE_IGNORED: @@ -357,8 +271,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::Graphic; case ui::AX_ROLE_IMAGE_MAP_LINK: return QAccessible::Link; - case ui::AX_ROLE_INCREMENTOR: - return QAccessible::NoRole; // FIXME case ui::AX_ROLE_INLINE_TEXT_BOX: return QAccessible::EditableText; case ui::AX_ROLE_LABEL_TEXT: @@ -387,8 +299,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::NoRole; // FIXME case ui::AX_ROLE_MATH: return QAccessible::Equation; - case ui::AX_ROLE_MATTE: - return QAccessible::NoRole; // FIXME case ui::AX_ROLE_MENU: return QAccessible::PopupMenu; case ui::AX_ROLE_MENU_BAR: @@ -413,6 +323,8 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::Paragraph; case ui::AX_ROLE_POP_UP_BUTTON: return QAccessible::ComboBox; + case ui::AX_ROLE_PRE: + return QAccessible::Section; case ui::AX_ROLE_PRESENTATIONAL: return QAccessible::NoRole; // FIXME case ui::AX_ROLE_PROGRESS_INDICATOR: @@ -429,8 +341,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::RowHeader; case ui::AX_ROLE_RULER: return QAccessible::NoRole; // FIXME - case ui::AX_ROLE_RULER_MARKER: - return QAccessible::NoRole; // FIXME case ui::AX_ROLE_SCROLL_AREA: return QAccessible::Client; // FIXME case ui::AX_ROLE_SCROLL_BAR: @@ -439,8 +349,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::NoRole; // FIXME case ui::AX_ROLE_SEARCH: return QAccessible::Section; - case ui::AX_ROLE_SHEET: - return QAccessible::NoRole; // FIXME case ui::AX_ROLE_SLIDER: return QAccessible::Slider; case ui::AX_ROLE_SLIDER_THUMB: @@ -451,16 +359,12 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::NoRole; // FIXME case ui::AX_ROLE_SPLITTER: return QAccessible::Splitter; - case ui::AX_ROLE_SPLIT_GROUP: - return QAccessible::Splitter; case ui::AX_ROLE_STATIC_TEXT: return QAccessible::StaticText; case ui::AX_ROLE_STATUS: return QAccessible::StatusBar; case ui::AX_ROLE_SVG_ROOT: return QAccessible::Graphic; - case ui::AX_ROLE_SYSTEM_WIDE: - return QAccessible::NoRole; // FIXME case ui::AX_ROLE_TABLE: return QAccessible::Table; case ui::AX_ROLE_TABLE_HEADER_CONTAINER: @@ -473,8 +377,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::PageTabList; case ui::AX_ROLE_TAB_PANEL: return QAccessible::PageTab; - case ui::AX_ROLE_TEXT_AREA: - return QAccessible::EditableText; case ui::AX_ROLE_TEXT_FIELD: return QAccessible::EditableText; case ui::AX_ROLE_TIMER: @@ -493,8 +395,6 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::Tree; case ui::AX_ROLE_TREE_ITEM: return QAccessible::TreeItem; - case ui::AX_ROLE_VALUE_INDICATOR: - return QAccessible::Client; // FIXME case ui::AX_ROLE_WINDOW: return QAccessible::Window; } diff --git a/src/core/browser_accessibility_qt.h b/src/core/browser_accessibility_qt.h index 7d58f515e..d4f8ac0a5 100644 --- a/src/core/browser_accessibility_qt.h +++ b/src/core/browser_accessibility_qt.h @@ -55,9 +55,6 @@ class BrowserAccessibilityQt public: BrowserAccessibilityQt(); - // BrowserAccessibility - virtual void OnDataChanged() Q_DECL_OVERRIDE; - // QAccessibleInterface virtual bool isValid() const Q_DECL_OVERRIDE; virtual QObject *object() const Q_DECL_OVERRIDE; diff --git a/src/core/browser_context_adapter.cpp b/src/core/browser_context_adapter.cpp index fa51575e3..14f3b1c6c 100644 --- a/src/core/browser_context_adapter.cpp +++ b/src/core/browser_context_adapter.cpp @@ -40,6 +40,7 @@ #include "browser_context_qt.h" #include "content_client_qt.h" #include "download_manager_delegate_qt.h" +#include "permission_manager_qt.h" #include "web_engine_context.h" #include "web_engine_visited_links_manager.h" #include "url_request_context_getter_qt.h" @@ -132,6 +133,28 @@ DownloadManagerDelegateQt *BrowserContextAdapter::downloadManagerDelegate() return m_downloadManagerDelegate.data(); } +QWebEngineCookieStoreClient *BrowserContextAdapter::cookieStoreClient() +{ + return m_cookieStoreClient.data(); +} + +void BrowserContextAdapter::setCookieStoreClient(QWebEngineCookieStoreClient *client) +{ + m_cookieStoreClient = client; + if (m_browserContext->url_request_getter_.get()) + m_browserContext->url_request_getter_->updateStorageSettings(); +} + +QWebEngineUrlRequestInterceptor *BrowserContextAdapter::requestInterceptor() +{ + return m_requestInterceptor.data(); +} + +void BrowserContextAdapter::setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor) +{ + m_requestInterceptor = interceptor; +} + void BrowserContextAdapter::addClient(BrowserContextAdapterClient *adapterClient) { m_clients.append(adapterClient); @@ -340,4 +363,19 @@ UserScriptControllerHost *BrowserContextAdapter::userScriptController() return m_userScriptController.data(); } +void BrowserContextAdapter::permissionRequestReply(const QUrl &origin, PermissionType type, bool reply) +{ + static_cast<PermissionManagerQt*>(browserContext()->GetPermissionManager())->permissionRequestReply(origin, type, reply); +} + +QString BrowserContextAdapter::httpAcceptLanguage() const +{ + return m_httpAcceptLanguage; +} + +void BrowserContextAdapter::setHttpAcceptLanguage(const QString &httpAcceptLanguage) +{ + m_httpAcceptLanguage = httpAcceptLanguage; +} + } // namespace QtWebEngineCore diff --git a/src/core/browser_context_adapter.h b/src/core/browser_context_adapter.h index 42787bc23..d58d8a4be 100644 --- a/src/core/browser_context_adapter.h +++ b/src/core/browser_context_adapter.h @@ -40,11 +40,15 @@ #include "qtwebenginecoreglobal.h" #include <QList> +#include <QPointer> #include <QScopedPointer> #include <QSharedData> #include <QString> #include <QVector> +#include "api/qwebenginecookiestoreclient.h" +#include "api/qwebengineurlrequestinterceptor.h" + QT_FORWARD_DECLARE_CLASS(QObject) namespace QtWebEngineCore { @@ -69,6 +73,12 @@ public: WebEngineVisitedLinksManager *visitedLinksManager(); DownloadManagerDelegateQt *downloadManagerDelegate(); + QWebEngineCookieStoreClient *cookieStoreClient(); + void setCookieStoreClient(QWebEngineCookieStoreClient *client); + + QWebEngineUrlRequestInterceptor* requestInterceptor(); + void setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor); + QList<BrowserContextAdapterClient*> clients() { return m_clients; } void addClient(BrowserContextAdapterClient *adapterClient); void removeClient(BrowserContextAdapterClient *adapterClient); @@ -113,6 +123,13 @@ public: TrackVisitedLinksOnDisk, }; + enum PermissionType { + UnsupportedPermission = 0, + GeolocationPermission = 1, +// Reserved: +// NotificationPermission = 2, + }; + HttpCacheType httpCacheType() const; void setHttpCacheType(BrowserContextAdapter::HttpCacheType); @@ -132,6 +149,11 @@ public: void updateCustomUrlSchemeHandlers(); UserScriptControllerHost *userScriptController(); + void permissionRequestReply(const QUrl &origin, PermissionType type, bool reply); + + QString httpAcceptLanguage() const; + void setHttpAcceptLanguage(const QString &httpAcceptLanguage); + private: QString m_name; bool m_offTheRecord; @@ -139,11 +161,14 @@ private: QScopedPointer<WebEngineVisitedLinksManager> m_visitedLinksManager; QScopedPointer<DownloadManagerDelegateQt> m_downloadManagerDelegate; QScopedPointer<UserScriptControllerHost> m_userScriptController; + QPointer<QWebEngineCookieStoreClient> m_cookieStoreClient; + QPointer<QWebEngineUrlRequestInterceptor> m_requestInterceptor; QString m_dataPath; QString m_cachePath; QString m_httpUserAgent; HttpCacheType m_httpCacheType; + QString m_httpAcceptLanguage; PersistentCookiesPolicy m_persistentCookiesPolicy; VisitedLinksPolicy m_visitedLinksPolicy; QVector<CustomUrlSchemeHandler*> m_customUrlSchemeHandlers; diff --git a/src/core/browser_context_qt.cpp b/src/core/browser_context_qt.cpp index 7f285b1e5..28486cced 100644 --- a/src/core/browser_context_qt.cpp +++ b/src/core/browser_context_qt.cpp @@ -38,9 +38,10 @@ #include "browser_context_adapter.h" #include "download_manager_delegate_qt.h" -#include "type_conversion.h" -#include "qtwebenginecoreglobal.h" +#include "permission_manager_qt.h" +#include "qtwebenginecoreglobal_p.h" #include "resource_context_qt.h" +#include "type_conversion.h" #include "url_request_context_getter_qt.h" #include "base/time/time.h" @@ -134,6 +135,18 @@ content::SSLHostStateDelegate* BrowserContextQt::GetSSLHostStateDelegate() return 0; } +scoped_ptr<content::ZoomLevelDelegate> BrowserContextQt::CreateZoomLevelDelegate(const base::FilePath&) +{ + return nullptr; +} + +content::PermissionManager *BrowserContextQt::GetPermissionManager() +{ + if (!permissionManager) + permissionManager.reset(new PermissionManagerQt(m_adapter)); + return permissionManager.get(); +} + net::URLRequestContextGetter *BrowserContextQt::CreateRequestContext(content::ProtocolHandlerMap *protocol_handlers) { url_request_getter_ = new URLRequestContextGetterQt(m_adapter, protocol_handlers); diff --git a/src/core/browser_context_qt.h b/src/core/browser_context_qt.h index af36b55ab..eccd684a3 100644 --- a/src/core/browser_context_qt.h +++ b/src/core/browser_context_qt.h @@ -47,6 +47,7 @@ namespace QtWebEngineCore { class BrowserContextAdapter; +class PermissionManagerQt; class URLRequestContextGetterQt; class BrowserContextQt : public content::BrowserContext @@ -72,13 +73,17 @@ public: virtual content::PushMessagingService* GetPushMessagingService() Q_DECL_OVERRIDE; virtual content::SSLHostStateDelegate* GetSSLHostStateDelegate() Q_DECL_OVERRIDE; net::URLRequestContextGetter *CreateRequestContext(content::ProtocolHandlerMap *protocol_handlers); + virtual scoped_ptr<content::ZoomLevelDelegate> CreateZoomLevelDelegate(const base::FilePath& partition_path) Q_DECL_OVERRIDE; + virtual content::PermissionManager *GetPermissionManager() Q_DECL_OVERRIDE; + + BrowserContextAdapter *adapter() { return m_adapter; } - BrowserContextAdapter* adapter() { return m_adapter; } private: friend class ContentBrowserClientQt; friend class WebContentsAdapter; scoped_ptr<content::ResourceContext> resourceContext; scoped_refptr<URLRequestContextGetterQt> url_request_getter_; + scoped_ptr<PermissionManagerQt> permissionManager; BrowserContextAdapter *m_adapter; friend class BrowserContextAdapter; diff --git a/src/core/chrome_qt.gyp b/src/core/chrome_qt.gyp index 703ce7525..0f30b7a04 100644 --- a/src/core/chrome_qt.gyp +++ b/src/core/chrome_qt.gyp @@ -19,6 +19,8 @@ '<(chromium_src_dir)/chrome/browser/media/desktop_streams_registry.cc', '<(chromium_src_dir)/chrome/browser/media/desktop_streams_registry.h', '<(chromium_src_dir)/chrome/browser/media/desktop_media_list.h', + '<(chromium_src_dir)/chrome/common/chrome_switches.cc', + '<(chromium_src_dir)/chrome/common/chrome_switches.h', '<(chromium_src_dir)/chrome/common/localized_error.cc', '<(chromium_src_dir)/chrome/common/localized_error.h', ], diff --git a/src/core/chromium_gpu_helper.cpp b/src/core/chromium_gpu_helper.cpp index ef574eccd..9dfc498ad 100644 --- a/src/core/chromium_gpu_helper.cpp +++ b/src/core/chromium_gpu_helper.cpp @@ -43,18 +43,18 @@ // Including gpu/command_buffer headers before content/gpu headers makes sure that // guards are defined to prevent duplicate definition errors with forward declared // GL typedefs cascading through content header includes. +#include "gpu/command_buffer/service/sync_point_manager.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/texture_manager.h" #include "content/common/gpu/gpu_channel_manager.h" -#include "content/common/gpu/sync_point_manager.h" #include "content/gpu/gpu_child_thread.h" #ifdef Q_OS_QNX #include "content/common/gpu/stream_texture_qnx.h" #endif -static void addSyncPointCallbackDelegate(content::SyncPointManager *syncPointManager, uint32 sync_point, const base::Closure& callback) +static void addSyncPointCallbackDelegate(gpu::SyncPointManager *syncPointManager, uint32 sync_point, const base::Closure& callback) { syncPointManager->AddSyncPointCallback(sync_point, callback); } @@ -78,13 +78,13 @@ base::MessageLoop *gpu_message_loop() return content::GpuChildThread::instance()->message_loop(); } -content::SyncPointManager *sync_point_manager() +gpu::SyncPointManager *sync_point_manager() { content::GpuChannelManager *gpuChannelManager = content::GpuChildThread::instance()->ChannelManager(); return gpuChannelManager->sync_point_manager(); } -void AddSyncPointCallbackOnGpuThread(base::MessageLoop *gpuMessageLoop, content::SyncPointManager *syncPointManager, uint32 sync_point, const base::Closure& callback) +void AddSyncPointCallbackOnGpuThread(base::MessageLoop *gpuMessageLoop, gpu::SyncPointManager *syncPointManager, uint32 sync_point, const base::Closure& callback) { // We need to set our callback from the GPU thread, where the SyncPointManager lives. gpuMessageLoop->PostTask(FROM_HERE, base::Bind(&addSyncPointCallbackDelegate, make_scoped_refptr(syncPointManager), sync_point, callback)); diff --git a/src/core/chromium_gpu_helper.h b/src/core/chromium_gpu_helper.h index 936ad1d24..6242dd068 100644 --- a/src/core/chromium_gpu_helper.h +++ b/src/core/chromium_gpu_helper.h @@ -47,12 +47,9 @@ namespace base { class MessageLoop; } -namespace content { -class SyncPointManager; -} - namespace gpu { struct Mailbox; +class SyncPointManager; namespace gles2 { class MailboxManager; class Texture; @@ -66,10 +63,10 @@ class Texture; QMap<uint32, gfx::TransferableFence> transferFences(); base::MessageLoop *gpu_message_loop(); -content::SyncPointManager *sync_point_manager(); +gpu::SyncPointManager *sync_point_manager(); gpu::gles2::MailboxManager *mailbox_manager(); -void AddSyncPointCallbackOnGpuThread(base::MessageLoop *gpuMessageLoop, content::SyncPointManager *syncPointManager, uint32 sync_point, const base::Closure& callback); +void AddSyncPointCallbackOnGpuThread(base::MessageLoop *gpuMessageLoop, gpu::SyncPointManager *syncPointManager, uint32 sync_point, const base::Closure& callback); gpu::gles2::Texture* ConsumeTexture(gpu::gles2::MailboxManager *mailboxManager, unsigned target, const gpu::Mailbox& mailbox); unsigned int service_id(gpu::gles2::Texture *tex); diff --git a/src/core/chromium_overrides.cpp b/src/core/chromium_overrides.cpp index 5af8a6ad8..b9ce722dd 100644 --- a/src/core/chromium_overrides.cpp +++ b/src/core/chromium_overrides.cpp @@ -37,8 +37,9 @@ #include "chromium_overrides.h" #include "gl_context_qt.h" -#include "qtwebenginecoreglobal.h" +#include "qtwebenginecoreglobal_p.h" #include "web_contents_view_qt.h" + #include "base/values.h" #include "content/browser/renderer_host/pepper/pepper_truetype_font_list.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" @@ -47,6 +48,8 @@ #include <QGuiApplication> #include <QScreen> #include <QWindow> +#include <QFontDatabase> +#include <QStringList> #if defined(USE_X11) #include "ui/gfx/x/x11_types.h" @@ -115,8 +118,17 @@ namespace content { // content/common/font_list.h scoped_ptr<base::ListValue> GetFontList_SlowBlocking() { - QT_NOT_USED - return scoped_ptr<base::ListValue>(new base::ListValue); + scoped_ptr<base::ListValue> font_list(new base::ListValue); + + QFontDatabase database; + for (auto family : database.families()){ + base::ListValue* font_item = new base::ListValue(); + font_item->Append(new base::StringValue(family.toStdString())); + font_item->Append(new base::StringValue(family.toStdString())); // should be localized name. + // TODO: Support localized family names. + font_list->Append(font_item); + } + return font_list.Pass(); } #if defined(ENABLE_PLUGINS) @@ -142,39 +154,6 @@ OSExchangeData::Provider* OSExchangeData::CreateProvider() return 0; } -} - -namespace gfx { - -// Stubs for these unused functions that are stripped in case -// of a release aura build but a debug build needs the symbols. - -RenderText* RenderText::CreateNativeInstance() -{ - QT_NOT_USED; - return 0; -} - -#if defined(OS_LINUX) -PlatformFont* PlatformFont::CreateDefault() -{ - QT_NOT_USED; - return 0; -} - -PlatformFont* PlatformFont::CreateFromNativeFont(NativeFont) -{ - QT_NOT_USED; - return 0; -} - -PlatformFont* PlatformFont::CreateFromNameAndSize(const std::string&, int) -{ - QT_NOT_USED; - return 0; -} -#endif - -} // namespace gfx +} // namespace ui #endif // defined(USE_AURA) && !defined(USE_OZONE) diff --git a/src/core/clipboard_qt.cpp b/src/core/clipboard_qt.cpp index 797f5c7f4..206392840 100644 --- a/src/core/clipboard_qt.cpp +++ b/src/core/clipboard_qt.cpp @@ -331,7 +331,7 @@ SkBitmap ClipboardQt::ReadImage(ui::ClipboardType type) const const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData(type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection); QImage image = qvariant_cast<QImage>(mimeData->imageData()); - Q_ASSERT(image.format() == QImage::Format_ARGB32); + image = image.convertToFormat(QImage::Format_ARGB32); SkBitmap bitmap; bitmap.setInfo(SkImageInfo::MakeN32(image.width(), image.height(), kOpaque_SkAlphaType)); bitmap.setPixels(const_cast<uchar*>(image.constBits())); @@ -361,7 +361,7 @@ void ClipboardQt::ReadData(const FormatType& format, std::string* result) const *result = std::string(byteArray.constData(), byteArray.length()); } -uint64 ClipboardQt::GetSequenceNumber(ui::ClipboardType type) +uint64 ClipboardQt::GetSequenceNumber(ui::ClipboardType type) const { return clipboardChangeObserver()->getSequenceNumber(type == ui::CLIPBOARD_TYPE_COPY_PASTE ? QClipboard::Clipboard : QClipboard::Selection); } diff --git a/src/core/clipboard_qt.h b/src/core/clipboard_qt.h index 4c7e6ab59..ee1fc7440 100644 --- a/src/core/clipboard_qt.h +++ b/src/core/clipboard_qt.h @@ -62,7 +62,7 @@ private: class ClipboardQt : public ui::Clipboard { public: - virtual uint64 GetSequenceNumber(ui::ClipboardType type) Q_DECL_OVERRIDE; + virtual uint64 GetSequenceNumber(ui::ClipboardType type) const Q_DECL_OVERRIDE; virtual bool IsFormatAvailable(const FormatType& format, ui::ClipboardType type) const Q_DECL_OVERRIDE; virtual void Clear(ui::ClipboardType type) Q_DECL_OVERRIDE; virtual void ReadAvailableTypes(ui::ClipboardType type, std::vector<base::string16>* types, bool* contains_filenames) const Q_DECL_OVERRIDE; diff --git a/src/core/common/qt_messages.h b/src/core/common/qt_messages.h index c692ee5ca..25a995b27 100644 --- a/src/core/common/qt_messages.h +++ b/src/core/common/qt_messages.h @@ -31,6 +31,9 @@ IPC_MESSAGE_ROUTED1(QtRenderViewObserver_FetchDocumentMarkup, IPC_MESSAGE_ROUTED1(QtRenderViewObserver_FetchDocumentInnerText, uint64 /* requestId */) +IPC_MESSAGE_ROUTED1(QtRenderViewObserver_SetBackgroundColor, + uint32 /* color */) + IPC_MESSAGE_ROUTED1(WebChannelIPCTransport_Message, std::vector<char> /*binaryJSON*/) // User scripts messages diff --git a/src/core/config/desktop_linux.pri b/src/core/config/desktop_linux.pri index 041b094a1..cb4efa607 100644 --- a/src/core/config/desktop_linux.pri +++ b/src/core/config/desktop_linux.pri @@ -15,7 +15,23 @@ GYP_CONFIG += \ use_pango=0 \ host_clang=0 \ clang=0 \ + enable_plugins=1 \ +contains(QT_CONFIG, system-zlib): config_system_minizip: GYP_CONFIG += use_system_zlib=1 +contains(QT_CONFIG, system-png): GYP_CONFIG += use_system_libpng=1 contains(QT_CONFIG, system-jpeg): GYP_CONFIG += use_system_libjpeg=1 +config_system_libevent: GYP_CONFIG += use_system_libevent=1 +config_system_libwebp: GYP_CONFIG += use_system_libwebp=1 +config_system_libsrtp: GYP_CONFIG += use_system_libsrtp=1 +config_system_libxslt: GYP_CONFIG += use_system_libxml=1 +config_system_flac: GYP_CONFIG += use_system_flac=1 +config_system_jsoncpp: GYP_CONFIG += use_system_jsoncpp=1 +config_system_opus: GYP_CONFIG += use_system_opus=1 +config_system_snappy: GYP_CONFIG += use_system_snappy=1 +config_system_speex: GYP_CONFIG += use_system_speex=1 +config_system_vpx: GYP_CONFIG += use_system_libvpx=1 + +contains(WEBENGINE_CONFIG, use_system_icu): GYP_CONFIG += use_system_icu=1 +contains(WEBENGINE_CONFIG, use_system_ffmpeg): GYP_CONFIG += use_system_ffmpeg=1 !contains(QT_CONFIG, pulseaudio): GYP_CONFIG += use_pulseaudio=0 diff --git a/src/core/config/embedded_linux.pri b/src/core/config/embedded_linux.pri index cc8c40f8e..0133dc6b0 100644 --- a/src/core/config/embedded_linux.pri +++ b/src/core/config/embedded_linux.pri @@ -1,7 +1,6 @@ GYP_ARGS += "-D qt_os=\"embedded_linux\" -I config/embedded_linux.gypi" GYP_CONFIG += \ - build_ffmpegsumo=1 \ clang=0 \ desktop_linux=0 \ disable_nacl=1 \ @@ -44,11 +43,25 @@ GYP_CONFIG += \ use_ozone=1 \ use_pango=0 \ use_system_fontconfig=1 \ - use_system_icu=1 \ icu_use_data_file_flag=0 \ use_x11=0 \ v8_use_snapshot=false \ want_separate_host_toolset=1 \ +contains(QT_CONFIG, system-zlib): config_system_minizip: GYP_CONFIG += use_system_zlib=1 +contains(QT_CONFIG, system-png): GYP_CONFIG += use_system_libpng=1 contains(QT_CONFIG, system-jpeg): GYP_CONFIG += use_system_libjpeg=1 !contains(QT_CONFIG, pulseaudio): GYP_CONFIG += use_pulseaudio=0 +config_system_libevent: GYP_CONFIG += use_system_libevent=1 +config_system_libwebp: GYP_CONFIG += use_system_libwebp=1 +config_system_libsrtp: GYP_CONFIG += use_system_libsrtp=1 +config_system_libxslt: GYP_CONFIG += use_system_libxml=1 +config_system_flac: GYP_CONFIG += use_system_flac=1 +config_system_jsoncpp: GYP_CONFIG += use_system_jsoncpp=1 +config_system_opus: GYP_CONFIG += use_system_opus=1 +config_system_snappy: GYP_CONFIG += use_system_snappy=1 +config_system_speex: GYP_CONFIG += use_system_speex=1 +config_system_vpx: GYP_CONFIG += use_system_libvpx=1 + +contains(WEBENGINE_CONFIG, use_system_icu): GYP_CONFIG += use_system_icu=1 +contains(WEBENGINE_CONFIG, use_system_ffmpeg): GYP_CONFIG += use_system_ffmpeg=1 diff --git a/src/core/config/mac_osx.pri b/src/core/config/mac_osx.pri index 3f42b6fd7..93c77623c 100644 --- a/src/core/config/mac_osx.pri +++ b/src/core/config/mac_osx.pri @@ -14,7 +14,8 @@ GYP_CONFIG += \ mac_sdk_min=\"10.7\" \ mac_deployment_target=\"$${QMAKE_MACOSX_DEPLOYMENT_TARGET}\" \ make_clang_dir=\"$${QMAKE_CLANG_DIR}\" \ - clang_use_chrome_plugins=0 + clang_use_chrome_plugins=0 \ + enable_plugins=1 QMAKE_MAC_SDK_PATH = "$$eval(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.path)" exists($$QMAKE_MAC_SDK_PATH): GYP_CONFIG += mac_sdk_path=\"$${QMAKE_MAC_SDK_PATH}\" diff --git a/src/core/config/windows.pri b/src/core/config/windows.pri index f7644c83b..602afbc67 100644 --- a/src/core/config/windows.pri +++ b/src/core/config/windows.pri @@ -28,3 +28,17 @@ contains(QT_CONFIG, angle) { GYP_ARGS += "-D qt_gl=\"opengl\"" } +msvc { + equals(MSVC_VER, 12.0) { + MSVS_VERSION = 2013 + } else:equals(MSVC_VER, 14.0) { + MSVS_VERSION = 2015 + } else { + fatal("Visual Studio compiler version \"$$MSVC_VER\" is not supported by Qt WebEngine") + } + + GYP_ARGS += "-G msvs_version=$$MSVS_VERSION" + +} else { + fatal("Qt WebEngine for Windows can only be built with the Microsoft Visual Studio C++ compiler") +} diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp index fdfbaf0f5..91cd0b0c4 100644 --- a/src/core/content_browser_client_qt.cpp +++ b/src/core/content_browser_client_qt.cpp @@ -56,6 +56,7 @@ #include "ui/gl/gl_context.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_share_group.h" +#include "ui/gl/gpu_timing.h" #include "access_token_store_qt.h" #include "browser_context_adapter.h" @@ -74,6 +75,12 @@ #include "web_engine_context.h" #include "web_engine_library_info.h" +#if defined(ENABLE_PLUGINS) +#include "content/public/browser/browser_ppapi_host.h" +#include "ppapi/host/ppapi_host.h" +#include "renderer/pepper/pepper_host_factory_qt.h" +#endif + #include <QGuiApplication> #include <QLocale> #include <QOpenGLContext> @@ -277,7 +284,11 @@ public: virtual bool MakeCurrent(gfx::GLSurface *) Q_DECL_OVERRIDE { Q_UNREACHABLE(); return false; } virtual void ReleaseCurrent(gfx::GLSurface *) Q_DECL_OVERRIDE { Q_UNREACHABLE(); } virtual bool IsCurrent(gfx::GLSurface *) Q_DECL_OVERRIDE { Q_UNREACHABLE(); return false; } - virtual void SetSwapInterval(int) Q_DECL_OVERRIDE { Q_UNREACHABLE(); } + virtual void OnSetSwapInterval(int) Q_DECL_OVERRIDE { Q_UNREACHABLE(); } + virtual scoped_refptr<gfx::GPUTimingClient> CreateGPUTimingClient() Q_DECL_OVERRIDE + { + return nullptr; + } private: void *m_handle; @@ -360,9 +371,8 @@ content::MediaObserver *ContentBrowserClientQt::GetMediaObserver() return MediaCaptureDevicesDispatcher::GetInstance(); } -void ContentBrowserClientQt::OverrideWebkitPrefs(content::RenderViewHost *rvh, const GURL &url, content::WebPreferences *web_prefs) +void ContentBrowserClientQt::OverrideWebkitPrefs(content::RenderViewHost *rvh, content::WebPreferences *web_prefs) { - Q_UNUSED(url); if (content::WebContents *webContents = rvh->GetDelegate()->GetAsWebContents()) static_cast<WebContentsDelegateQt*>(webContents->GetDelegate())->overrideWebPreferences(webContents, web_prefs); } @@ -402,41 +412,6 @@ void ContentBrowserClientQt::AllowCertificateError(int render_process_id, int re contentsDelegate->allowCertificateError(errorController); } -void ContentBrowserClientQt::RequestPermission(content::PermissionType permission, - content::WebContents* web_contents, - int bridge_id, - const GURL& requesting_frame, - bool user_gesture, - const base::Callback<void(bool)>& result_callback) -{ - Q_UNUSED(bridge_id); - Q_UNUSED(user_gesture); - WebContentsDelegateQt* contentsDelegate = static_cast<WebContentsDelegateQt*>(web_contents->GetDelegate()); - Q_ASSERT(contentsDelegate); - if (permission == content::PERMISSION_GEOLOCATION) - contentsDelegate->requestGeolocationPermission(requesting_frame, result_callback); - else - result_callback.Run(false); -} - - -void ContentBrowserClientQt::CancelPermissionRequest(content::PermissionType permission, - content::WebContents* web_contents, - int bridge_id, - const GURL& requesting_frame) -{ - Q_UNUSED(bridge_id); - WebContentsDelegateQt* contentsDelegate = static_cast<WebContentsDelegateQt*>(web_contents->GetDelegate()); - Q_ASSERT(contentsDelegate); - if (permission == content::PERMISSION_GEOLOCATION) - contentsDelegate->cancelGeolocationPermissionRequest(requesting_frame); -} - -blink::WebNotificationPermission ContentBrowserClientQt::CheckDesktopNotificationPermission(const GURL&, content::ResourceContext *, int ) -{ - return blink::WebNotificationPermission::WebNotificationPermissionDenied; -} - content::LocationProvider *ContentBrowserClientQt::OverrideSystemLocationProvider() { #ifdef QT_USE_POSITIONING @@ -451,6 +426,11 @@ std::string ContentBrowserClientQt::GetApplicationLocale() return WebEngineLibraryInfo::getApplicationLocale(); } +std::string ContentBrowserClientQt::GetAcceptLangs(content::BrowserContext *context) +{ + return static_cast<BrowserContextQt*>(context)->adapter()->httpAcceptLanguage().toStdString(); +} + void ContentBrowserClientQt::AppendExtraCommandLineSwitches(base::CommandLine* command_line, int child_process_id) { Q_UNUSED(child_process_id); @@ -460,6 +440,13 @@ void ContentBrowserClientQt::AppendExtraCommandLineSwitches(base::CommandLine* c command_line->AppendSwitchASCII(switches::kLang, GetApplicationLocale()); } +#if defined(ENABLE_PLUGINS) + void ContentBrowserClientQt::DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) { + browser_host->GetPpapiHost()->AddHostFactoryFilter( + scoped_ptr<ppapi::host::HostFactory>(new QtWebEngineCore::PepperHostFactoryQt(browser_host))); + } +#endif + content::DevToolsManagerDelegate* ContentBrowserClientQt::GetDevToolsManagerDelegate() { return new DevToolsManagerDelegateQt; diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h index 0af5ae9d3..eea7d2a22 100644 --- a/src/core/content_browser_client_qt.h +++ b/src/core/content_browser_client_qt.h @@ -40,7 +40,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "content/public/browser/content_browser_client.h" -#include "third_party/WebKit/public/platform/WebNotificationPermission.h" +#include "third_party/WebKit/public/platform/modules/notifications/WebNotificationPermission.h" #include <QtCore/qcompilerdetection.h> // Needed for Q_DECL_OVERRIDE @@ -51,6 +51,11 @@ class URLRequestContextGetter; namespace content { class BrowserContext; class BrowserMainParts; + +#if defined(ENABLE_PLUGINS) +class BrowserPpapiHost; +#endif + class DevToolsManagerDelegate; class RenderProcessHost; class RenderViewHostDelegateView; @@ -83,7 +88,7 @@ public: virtual content::MediaObserver* GetMediaObserver() Q_DECL_OVERRIDE; virtual content::AccessTokenStore* CreateAccessTokenStore() Q_DECL_OVERRIDE; virtual content::QuotaPermissionContext *CreateQuotaPermissionContext() Q_DECL_OVERRIDE; - virtual void OverrideWebkitPrefs(content::RenderViewHost *, const GURL &, content::WebPreferences *) Q_DECL_OVERRIDE; + virtual void OverrideWebkitPrefs(content::RenderViewHost *, content::WebPreferences *) Q_DECL_OVERRIDE; virtual void AllowCertificateError( int render_process_id, int render_frame_id, @@ -96,26 +101,18 @@ public: bool expired_previous_decision, const base::Callback<void(bool)>& callback, content::CertificateRequestResultType* result) Q_DECL_OVERRIDE; - virtual void RequestPermission( - content::PermissionType permission, - content::WebContents* web_contents, - int bridge_id, - const GURL& requesting_frame, - bool user_gesture, - const base::Callback<void(bool)>& result_callback) Q_DECL_OVERRIDE; - virtual void CancelPermissionRequest(content::PermissionType permission, - content::WebContents* web_contents, - int bridge_id, - const GURL& requesting_frame) Q_DECL_OVERRIDE; content::LocationProvider* OverrideSystemLocationProvider() Q_DECL_OVERRIDE; content::DevToolsManagerDelegate *GetDevToolsManagerDelegate() Q_DECL_OVERRIDE; virtual net::URLRequestContextGetter *CreateRequestContext(content::BrowserContext *browser_context, content::ProtocolHandlerMap *protocol_handlers, content::URLRequestInterceptorScopedVector request_interceptorss) Q_DECL_OVERRIDE; - virtual blink::WebNotificationPermission CheckDesktopNotificationPermission(const GURL& source_origin, content::ResourceContext* context, int render_process_id) Q_DECL_OVERRIDE; - virtual std::string GetApplicationLocale() Q_DECL_OVERRIDE; + std::string GetAcceptLangs(content::BrowserContext* context) Q_DECL_OVERRIDE; virtual void AppendExtraCommandLineSwitches(base::CommandLine* command_line, int child_process_id) Q_DECL_OVERRIDE; +#if defined(ENABLE_PLUGINS) + virtual void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) Q_DECL_OVERRIDE; +#endif + private: BrowserMainPartsQt* m_browserMainParts; scoped_ptr<ResourceDispatcherHostDelegateQt> m_resourceDispatcherHostDelegate; diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp index 20a8df75e..01e1fe383 100644 --- a/src/core/content_client_qt.cpp +++ b/src/core/content_client_qt.cpp @@ -36,11 +36,119 @@ #include "content_client_qt.h" +#include "base/command_line.h" #include "base/strings/string_piece.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "content/public/common/content_constants.h" #include "content/public/common/user_agent.h" #include "ui/base/layout.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" +#include "type_conversion.h" + +#include <QCoreApplication> +#include <QFile> +#include <QStringBuilder> + +#if defined(ENABLE_PLUGINS) +#include "content/public/common/pepper_plugin_info.h" +#include "ppapi/shared_impl/ppapi_permissions.h" + +static const int32 kPepperFlashPermissions = ppapi::PERMISSION_DEV | + ppapi::PERMISSION_PRIVATE | + ppapi::PERMISSION_BYPASS_USER_GESTURE | + ppapi::PERMISSION_FLASH; + +namespace switches { +const char kPpapiFlashPath[] = "ppapi-flash-path"; +const char kPpapiFlashVersion[] = "ppapi-flash-version"; +} + +// Adopted from chrome_content_client.cc +content::PepperPluginInfo CreatePepperFlashInfo(const base::FilePath& path, const std::string& version) +{ + content::PepperPluginInfo plugin; + + plugin.is_out_of_process = true; + plugin.name = content::kFlashPluginName; + plugin.path = path; + plugin.permissions = kPepperFlashPermissions; + + std::vector<std::string> flash_version_numbers; + base::SplitString(version, '.', &flash_version_numbers); + if (flash_version_numbers.size() < 1) + flash_version_numbers.push_back("11"); + else if (flash_version_numbers[0].empty()) + flash_version_numbers[0] = "11"; + if (flash_version_numbers.size() < 2) + flash_version_numbers.push_back("2"); + if (flash_version_numbers.size() < 3) + flash_version_numbers.push_back("999"); + if (flash_version_numbers.size() < 4) + flash_version_numbers.push_back("999"); + + // E.g., "Shockwave Flash 10.2 r154": + plugin.description = plugin.name + " " + flash_version_numbers[0] + "." + flash_version_numbers[1] + " r" + flash_version_numbers[2]; + plugin.version = JoinString(flash_version_numbers, '.'); + content::WebPluginMimeType swf_mime_type(content::kFlashPluginSwfMimeType, + content::kFlashPluginSwfExtension, + content::kFlashPluginSwfDescription); + plugin.mime_types.push_back(swf_mime_type); + content::WebPluginMimeType spl_mime_type(content::kFlashPluginSplMimeType, + content::kFlashPluginSplExtension, + content::kFlashPluginSplDescription); + plugin.mime_types.push_back(spl_mime_type); + + return plugin; +} + +void AddPepperFlashFromSystem(std::vector<content::PepperPluginInfo>* plugins) +{ + QStringList pluginPaths; +#if defined(Q_OS_WIN) && defined(Q_PROCESSOR_X86_32) + QDir pluginDir("C:/Windows/SysWOW64/Macromed/Flash"); + pluginDir.setFilter(QDir::Files); + QStringList nameFilters("pepflashplayer*.dll"); + pluginPaths << pluginDir.entryList(nameFilters); +#endif +#if defined(Q_OS_OSX) + pluginPaths << "/Library/Internet Plug-Ins/PepperFlashPlayer/PepperFlashPlayer.plugin"; // Mac OS X +#endif +#if defined(Q_OS_LINUX) + pluginPaths << "/usr/lib/pepperflashplugin-nonfree/libpepflashplayer.so" // Ubuntu + << "/usr/lib/PepperFlash/libpepflashplayer.so" // Arch + << "/usr/lib64/chromium/PepperFlash/libpepflashplayer.so"; // OpenSuSE +#endif + for (auto it = pluginPaths.constBegin(); it != pluginPaths.constEnd(); ++it) { + if (!QFile(*it).exists()) + continue; + plugins->push_back(CreatePepperFlashInfo(QtWebEngineCore::toFilePath(*it), std::string())); + return; + } +} + +void AddPepperFlashFromCommandLine(std::vector<content::PepperPluginInfo>* plugins) +{ + const base::CommandLine::StringType flash_path = base::CommandLine::ForCurrentProcess()->GetSwitchValueNative(switches::kPpapiFlashPath); + if (flash_path.empty() || !QFile(QtWebEngineCore::toQt(flash_path)).exists()) + return; + + // Read pepper flash plugin version from command-line. (e.g. 16.0.0.235) + std::string flash_version = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kPpapiFlashVersion); + plugins->push_back(CreatePepperFlashInfo(base::FilePath(flash_path), flash_version)); +} + +namespace QtWebEngineCore { + +void ContentClientQt::AddPepperPlugins(std::vector<content::PepperPluginInfo>* plugins) +{ + AddPepperFlashFromSystem(plugins); + AddPepperFlashFromCommandLine(plugins); +} + +} +#endif #include <QCoreApplication> #include <QStringBuilder> diff --git a/src/core/content_client_qt.h b/src/core/content_client_qt.h index f68282dcf..309e049dc 100644 --- a/src/core/content_client_qt.h +++ b/src/core/content_client_qt.h @@ -48,6 +48,10 @@ class ContentClientQt : public content::ContentClient { public: static std::string getUserAgent(); +#if defined(ENABLE_PLUGINS) + virtual void AddPepperPlugins(std::vector<content::PepperPluginInfo>* plugins) Q_DECL_OVERRIDE; +#endif + virtual base::StringPiece GetDataResource(int, ui::ScaleFactor) const Q_DECL_OVERRIDE; virtual std::string GetUserAgent() const Q_DECL_OVERRIDE { return getUserAgent(); } virtual base::string16 GetLocalizedString(int message_id) const Q_DECL_OVERRIDE; diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp index 4003823b1..0688fb015 100644 --- a/src/core/content_main_delegate_qt.cpp +++ b/src/core/content_main_delegate_qt.cpp @@ -72,7 +72,7 @@ void ContentMainDelegateQt::PreSandboxStartup() // Suppress info, warning and error messages per default. int logLevel = logging::LOG_FATAL; - CommandLine* parsedCommandLine = CommandLine::ForCurrentProcess(); + base::CommandLine* parsedCommandLine = base::CommandLine::ForCurrentProcess(); if (parsedCommandLine->HasSwitch(switches::kLoggingLevel)) { std::string logLevelValue = parsedCommandLine->GetSwitchValueASCII(switches::kLoggingLevel); int level = 0; diff --git a/src/core/cookie_monster_delegate_qt.cpp b/src/core/cookie_monster_delegate_qt.cpp new file mode 100644 index 000000000..6b808e76c --- /dev/null +++ b/src/core/cookie_monster_delegate_qt.cpp @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "cookie_monster_delegate_qt.h" + +#include "base/bind.h" +#include "content/public/browser/browser_thread.h" +#include "net/cookies/cookie_util.h" + +#include "api/qwebenginecookiestoreclient.h" +#include "api/qwebenginecookiestoreclient_p.h" +#include "type_conversion.h" + +#include <QStringBuilder> + +namespace QtWebEngineCore { + +static GURL sourceUrlForCookie(const QNetworkCookie &cookie) { + QString urlFragment = QString("%1%2").arg(cookie.domain()).arg(cookie.path()); + return net::cookie_util::CookieOriginToURL(urlFragment.toStdString(), /* is_https */ cookie.isSecure()); +} + +static void onSetCookieCallback(QWebEngineCookieStoreClientPrivate *client, qint64 callbackId, bool success) { + client->onSetCallbackResult(callbackId, success); +} + +static void onDeleteCookiesCallback(QWebEngineCookieStoreClientPrivate *client, qint64 callbackId, int numCookies) { + client->onDeleteCallbackResult(callbackId, numCookies); +} + +static void onGetAllCookiesCallback(QWebEngineCookieStoreClientPrivate *client, qint64 callbackId, const net::CookieList& cookies) { + QByteArray rawCookies; + for (auto&& cookie: cookies) + rawCookies += toQt(cookie).toRawForm() % QByteArrayLiteral("\n"); + + client->onGetAllCallbackResult(callbackId, rawCookies); +} + +CookieMonsterDelegateQt::CookieMonsterDelegateQt() + : m_client(0) + , m_cookieMonster(0) +{ + +} + +CookieMonsterDelegateQt::~CookieMonsterDelegateQt() +{ + +} + +bool CookieMonsterDelegateQt::hasCookieMonster() +{ + return m_cookieMonster.get(); +} + +void CookieMonsterDelegateQt::getAllCookies(quint64 callbackId) +{ + net::CookieMonster::GetCookieListCallback callback = base::Bind(&onGetAllCookiesCallback, m_client->d_func(), callbackId); + m_cookieMonster->GetAllCookiesAsync(callback); +} + +void CookieMonsterDelegateQt::setCookie(quint64 callbackId, const QNetworkCookie &cookie, const QUrl &origin) +{ + Q_ASSERT(hasCookieMonster()); + Q_ASSERT(m_client); + + net::CookieStore::SetCookiesCallback callback; + if (callbackId != CallbackDirectory::NoCallbackId) + callback = base::Bind(&onSetCookieCallback, m_client->d_func(), callbackId); + + net::CookieOptions options; + options.set_include_httponly(); + + GURL gurl = origin.isEmpty() ? sourceUrlForCookie(cookie) : toGurl(origin); + + m_cookieMonster->SetCookieWithOptionsAsync(gurl, cookie.toRawForm().toStdString(), options, callback); +} + +void CookieMonsterDelegateQt::deleteCookie(const QNetworkCookie &cookie, const QUrl &origin) +{ + Q_ASSERT(hasCookieMonster()); + Q_ASSERT(m_client); + + GURL gurl = origin.isEmpty() ? sourceUrlForCookie(cookie) : toGurl(origin); + + m_cookieMonster->DeleteCookieAsync(gurl, cookie.name().toStdString(), base::Closure()); +} + +void CookieMonsterDelegateQt::deleteSessionCookies(quint64 callbackId) +{ + Q_ASSERT(hasCookieMonster()); + Q_ASSERT(m_client); + + net::CookieMonster::DeleteCallback callback = base::Bind(&onDeleteCookiesCallback, m_client->d_func(), callbackId); + m_cookieMonster->DeleteSessionCookiesAsync(callback); +} + +void CookieMonsterDelegateQt::deleteAllCookies(quint64 callbackId) +{ + Q_ASSERT(hasCookieMonster()); + Q_ASSERT(m_client); + + net::CookieMonster::DeleteCallback callback = base::Bind(&onDeleteCookiesCallback, m_client->d_func(), callbackId); + m_cookieMonster->DeleteAllAsync(callback); +} + +void CookieMonsterDelegateQt::setCookieMonster(net::CookieMonster* monster) +{ + m_cookieMonster = monster; + + if (m_client) + m_client->d_func()->processPendingUserCookies(); +} + +void CookieMonsterDelegateQt::setClient(QWebEngineCookieStoreClient *client) +{ + m_client = client; + + if (!m_client) + return; + + m_client->d_ptr->delegate = this; + + if (hasCookieMonster()) + m_client->d_func()->processPendingUserCookies(); +} + +void CookieMonsterDelegateQt::OnCookieChanged(const net::CanonicalCookie& cookie, bool removed, ChangeCause cause) +{ + if (!m_client) + return; + m_client->d_ptr->onCookieChanged(toQt(cookie), removed); +} + +} diff --git a/src/core/cookie_monster_delegate_qt.h b/src/core/cookie_monster_delegate_qt.h new file mode 100644 index 000000000..e5e295853 --- /dev/null +++ b/src/core/cookie_monster_delegate_qt.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef COOKIE_MONSTER_DELEGATE_QT_H +#define COOKIE_MONSTER_DELEGATE_QT_H + +#include "qtwebenginecoreglobal.h" + +QT_WARNING_PUSH +// For some reason adding -Wno-unused-parameter to QMAKE_CXXFLAGS has no +// effect with clang, so use a pragma for these dirty chromium headers +QT_WARNING_DISABLE_CLANG("-Wunused-parameter") +#include "base/memory/ref_counted.h" +#include "net/cookies/cookie_monster.h" +QT_WARNING_POP + +#include <QList> +#include <QNetworkCookie> +#include <QPointer> + +QT_FORWARD_DECLARE_CLASS(QWebEngineCookieStoreClient) + +namespace QtWebEngineCore { + +// Extends net::CookieMonster::kDefaultCookieableSchemes with qrc, without enabling +// cookies for the file:// scheme, which is disabled by default in Chromium. +// Since qrc:// is similar to file:// and there are some unknowns about how +// to correctly handle file:// cookies, qrc:// should only be used for testing. +static const char* const kCookieableSchemes[] = + { "http", "https", "qrc", "ws", "wss" }; + +class QWEBENGINE_EXPORT CookieMonsterDelegateQt: public net::CookieMonsterDelegate { + QPointer<QWebEngineCookieStoreClient> m_client; + scoped_refptr<net::CookieMonster> m_cookieMonster; +public: + CookieMonsterDelegateQt(); + ~CookieMonsterDelegateQt(); + + bool hasCookieMonster(); + + void setCookie(quint64 callbackId, const QNetworkCookie &cookie, const QUrl &origin); + void deleteCookie(const QNetworkCookie &cookie, const QUrl &origin); + void getAllCookies(quint64 callbackId); + void deleteSessionCookies(quint64 callbackId); + void deleteAllCookies(quint64 callbackId); + + void setCookieMonster(net::CookieMonster* monster); + void setClient(QWebEngineCookieStoreClient *client); + + void OnCookieChanged(const net::CanonicalCookie& cookie, bool removed, ChangeCause cause) override; +}; + +} + +#endif // COOKIE_MONSTER_DELEGATE_QT_H diff --git a/src/core/core.pro b/src/core/core.pro index cf00f39cb..7f19a48ce 100644 --- a/src/core/core.pro +++ b/src/core/core.pro @@ -8,12 +8,16 @@ core_gyp_generator.file = core_gyp_generator.pro gyp_run.file = gyp_run.pro gyp_run.depends = core_gyp_generator +core_api.file = api/core_api.pro +core_api.depends = gyp_run + # This will take the compile output of ninja, and link+deploy the final binary. core_module.file = core_module.pro -core_module.depends = gyp_run +core_module.depends = core_api SUBDIRS += core_gyp_generator \ gyp_run \ + core_api \ core_module !win32 { diff --git a/src/core/core_common.pri b/src/core/core_common.pri index cefde4302..1ea4e1862 100644 --- a/src/core/core_common.pri +++ b/src/core/core_common.pri @@ -6,7 +6,7 @@ QT += qml quick webchannel QT_PRIVATE += quick-private gui-private core-private # Make QtCreator happy. -CHROMIUM_SRC_DIR = $$QTWEBENGINE_ROOT/$${getChromiumSrcDir()} +CHROMIUM_SRC_DIR = $$QTWEBENGINE_ROOT/$$getChromiumSrcDir() INCLUDEPATH += $$CHROMIUM_SRC_DIR qtHaveModule(positioning):QT += positioning diff --git a/src/core/core_gyp_generator.pro b/src/core/core_gyp_generator.pro index c745fd19e..1a2679a60 100644 --- a/src/core/core_gyp_generator.pro +++ b/src/core/core_gyp_generator.pro @@ -18,14 +18,14 @@ DEFINES += QT_NO_KEYWORDS \ # Assume that we want mobile touch and low-end hardware behaviors # whenever we are cross compiling. -cross_compile: DEFINES += QTWEBENGINE_MOBILE_SWITCHES +cross_compile: DEFINES += QTWEBENGINE_EMBEDDED_SWITCHES contains(QT_CONFIG, egl): CONFIG += egl else: DEFINES += QT_NO_EGL RESOURCES += devtools.qrc -INCLUDEPATH += $$PWD +INCLUDEPATH += $$PWD $$PWD/api SOURCES = \ access_token_store_qt.cpp \ @@ -42,12 +42,14 @@ SOURCES = \ content_client_qt.cpp \ content_browser_client_qt.cpp \ content_main_delegate_qt.cpp \ + cookie_monster_delegate_qt.cpp \ custom_protocol_handler.cpp \ custom_url_scheme_handler.cpp \ delegated_frame_node.cpp \ desktop_screen_qt.cpp \ dev_tools_http_handler_delegate_qt.cpp \ download_manager_delegate_qt.cpp \ + file_picker_controller.cpp \ gl_context_qt.cpp \ gl_surface_qt.cpp \ javascript_dialog_controller.cpp \ @@ -56,11 +58,19 @@ SOURCES = \ native_web_keyboard_event_qt.cpp \ network_delegate_qt.cpp \ ozone_platform_eglfs.cpp \ + permission_manager_qt.cpp \ process_main.cpp \ + proxy_config_service_qt.cpp \ + proxy_resolver_qt.cpp \ qrc_protocol_handler_qt.cpp \ qt_render_view_observer_host.cpp \ render_widget_host_view_qt.cpp \ renderer/content_renderer_client_qt.cpp \ + renderer/pepper/pepper_flash_browser_host_qt.cpp \ + renderer/pepper/pepper_flash_renderer_host_qt.cpp \ + renderer/pepper/pepper_host_factory_qt.cpp \ + renderer/pepper/pepper_renderer_host_factory_qt.cpp \ + renderer/qt_render_frame_observer.cpp \ renderer/qt_render_view_observer.cpp \ renderer/user_script_controller.cpp \ renderer/web_channel_ipc_transport.cpp \ @@ -103,6 +113,7 @@ HEADERS = \ content_client_qt.h \ content_browser_client_qt.h \ content_main_delegate_qt.h \ + cookie_monster_delegate_qt.h \ custom_protocol_handler.h \ custom_url_scheme_handler.h \ delegated_frame_node.h \ @@ -110,6 +121,7 @@ HEADERS = \ dev_tools_http_handler_delegate_qt.h \ download_manager_delegate_qt.h \ chromium_gpu_helper.h \ + file_picker_controller.h \ gl_context_qt.h \ gl_surface_qt.h \ javascript_dialog_controller_p.h \ @@ -118,13 +130,20 @@ HEADERS = \ media_capture_devices_dispatcher.h \ network_delegate_qt.h \ ozone_platform_eglfs.h \ + permission_manager_qt.h \ process_main.h \ + proxy_config_service_qt.h \ + proxy_resolver_qt.h \ qrc_protocol_handler_qt.h \ qt_render_view_observer_host.h \ - qtwebenginecoreglobal.h \ render_widget_host_view_qt.h \ render_widget_host_view_qt_delegate.h \ renderer/content_renderer_client_qt.h \ + renderer/pepper/pepper_flash_browser_host_qt.h \ + renderer/pepper/pepper_flash_renderer_host_qt.h \ + renderer/pepper/pepper_host_factory_qt.h \ + renderer/pepper/pepper_renderer_host_factory_qt.h \ + renderer/qt_render_frame_observer.h \ renderer/qt_render_view_observer.h \ renderer/user_script_controller.h \ renderer/web_channel_ipc_transport.h \ diff --git a/src/core/core_module.pro b/src/core/core_module.pro index e6a36332f..291aac916 100644 --- a/src/core/core_module.pro +++ b/src/core/core_module.pro @@ -9,10 +9,28 @@ QMAKE_INFO_PLIST = Info_mac.plist error("Could not find the linking information that gyp should have generated.") } -# We distribute the module binary but headers are only available in-tree. -CONFIG += no_module_headers +QMAKE_DOCS = $$PWD/doc/qtwebenginecore.qdocconf + load(qt_module) +api_library_name = qtwebenginecoreapi +api_library_path = $$OUT_PWD/api/$$getConfigDir() +LIBS_PRIVATE += -L$$api_library_path +CONFIG *= no_smart_library_merge +osx { + LIBS_PRIVATE += -Wl,-force_load,$${api_library_path}$${QMAKE_DIR_SEP}lib$${api_library_name}.a +} else:win32-msvc* { + LIBS_PRIVATE += /OPT:REF -l$$api_library_name +} else { + LIBS_PRIVATE += -Wl,-whole-archive -l$$api_library_name -Wl,-no-whole-archive +} + +win32-msvc* { + POST_TARGETDEPS += $${api_library_path}$${QMAKE_DIR_SEP}$${api_library_name}.lib +} else { + POST_TARGETDEPS += $${api_library_path}$${QMAKE_DIR_SEP}lib$${api_library_name}.a +} + # Using -Wl,-Bsymbolic-functions seems to confuse the dynamic linker # and doesn't let Chromium get access to libc symbols through dlsym. CONFIG -= bsymbolic_functions @@ -31,17 +49,8 @@ resources.files = $$REPACK_DIR/qtwebengine_resources.pak \ $$REPACK_DIR/qtwebengine_resources_100p.pak \ $$REPACK_DIR/qtwebengine_resources_200p.pak -PLUGIN_EXTENSION = .so -PLUGIN_PREFIX = lib -osx: PLUGIN_PREFIX = -win32 { - PLUGIN_EXTENSION = .dll - PLUGIN_PREFIX = -} icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat -plugins.files = $$OUT_PWD/$$getConfigDir()/$${PLUGIN_PREFIX}ffmpegsumo$${PLUGIN_EXTENSION} - !debug_and_release|!build_all|CONFIG(release, debug|release) { contains(QT_CONFIG, qt_framework) { locales.version = Versions @@ -50,12 +59,10 @@ plugins.files = $$OUT_PWD/$$getConfigDir()/$${PLUGIN_PREFIX}ffmpegsumo$${PLUGIN_ resources.path = Resources icu.version = Versions icu.path = Resources - plugins.version = Versions - plugins.path = Libraries # No files, this prepares the bundle Helpers symlink, process.pro will create the directories qtwebengineprocessplaceholder.version = Versions qtwebengineprocessplaceholder.path = Helpers - QMAKE_BUNDLE_DATA += icu locales resources plugins qtwebengineprocessplaceholder + QMAKE_BUNDLE_DATA += icu locales resources qtwebengineprocessplaceholder } else { locales.CONFIG += no_check_exist locales.path = $$[QT_INSTALL_TRANSLATIONS]/qtwebengine_locales @@ -63,9 +70,7 @@ plugins.files = $$OUT_PWD/$$getConfigDir()/$${PLUGIN_PREFIX}ffmpegsumo$${PLUGIN_ resources.path = $$[QT_INSTALL_DATA] icu.CONFIG += no_check_exist icu.path = $$[QT_INSTALL_DATA] - plugins.CONFIG += no_check_exist - plugins.path = $$[QT_INSTALL_PLUGINS]/qtwebengine - INSTALLS += icu locales resources plugins + INSTALLS += icu locales resources } !contains(QT_CONFIG, qt_framework): contains(QT_CONFIG, private_tests) { @@ -75,15 +80,7 @@ plugins.files = $$OUT_PWD/$$getConfigDir()/$${PLUGIN_PREFIX}ffmpegsumo$${PLUGIN_ unix: icu_rule.commands = if [ -e $$ICU_FILE ] ; then $$QMAKE_COPY $$ICU_FILE $$ICU_TARGET ; fi win32: icu_rule.commands = if exist $$ICU_FILE ( $$QMAKE_COPY $$ICU_FILE $$ICU_TARGET ) - PLUGIN_DIR = $$shell_path($$[QT_INSTALL_PLUGINS/get]/qtwebengine) - PLUGIN_TARGET = $$shell_path($$PLUGIN_DIR/$${PLUGIN_PREFIX}ffmpegsumo$${PLUGIN_EXTENSION}) - PLUGIN_FILE = $$shell_path($$OUT_PWD/$$getConfigDir()/$${PLUGIN_PREFIX}ffmpegsumo$${PLUGIN_EXTENSION}) - plugins_rule.target = $$PLUGIN_TARGET - unix: plugins_rule.commands = $$QMAKE_MKDIR $$PLUGIN_DIR && if [ -e $$PLUGIN_FILE ] ; then $$QMAKE_COPY $$PLUGIN_FILE $$PLUGIN_TARGET ; fi - win32: plugins_rule.commands = (if not exist $$PLUGIN_DIR ( $$QMAKE_MKDIR $$PLUGIN_DIR )) && \ - if exist $$PLUGIN_FILE ( $$QMAKE_COPY $$PLUGIN_FILE $$PLUGIN_TARGET ) - - QMAKE_EXTRA_TARGETS += icu_rule plugins_rule - PRE_TARGETDEPS += $$ICU_TARGET $$PLUGIN_TARGET + QMAKE_EXTRA_TARGETS += icu_rule + PRE_TARGETDEPS += $$ICU_TARGET } } diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp index 6f79d4952..dee381e15 100644 --- a/src/core/delegated_frame_node.cpp +++ b/src/core/delegated_frame_node.cpp @@ -76,6 +76,10 @@ #include <EGL/eglext.h> #endif +#ifndef GL_TIMEOUT_IGNORED +#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull +#endif + namespace QtWebEngineCore { class MailboxTexture : public QSGTexture, protected QOpenGLFunctions { @@ -205,7 +209,6 @@ static void waitChromiumSync(gfx::TransferableFence *sync) #endif break; case gfx::TransferableFence::ArbSync: -#ifdef GL_ARB_sync typedef void (QOPENGLF_APIENTRYP WaitSyncPtr)(GLsync sync, GLbitfield flags, GLuint64 timeout); static WaitSyncPtr glWaitSync_ = 0; if (!glWaitSync_) { @@ -214,7 +217,6 @@ static void waitChromiumSync(gfx::TransferableFence *sync) Q_ASSERT(glWaitSync_); } glWaitSync_(sync->arb.sync, 0, GL_TIMEOUT_IGNORED); -#endif break; } } @@ -250,7 +252,6 @@ static void deleteChromiumSync(gfx::TransferableFence *sync) #endif break; case gfx::TransferableFence::ArbSync: -#ifdef GL_ARB_sync typedef void (QOPENGLF_APIENTRYP DeleteSyncPtr)(GLsync sync); static DeleteSyncPtr glDeleteSync_ = 0; if (!glDeleteSync_) { @@ -260,7 +261,6 @@ static void deleteChromiumSync(gfx::TransferableFence *sync) } glDeleteSync_(sync->arb.sync); sync->reset(); -#endif break; } // If Chromium was able to create a sync, we should have been able to handle its type here too. @@ -409,7 +409,7 @@ void DelegatedFrameNode::preprocess() { QMutexLocker lock(&m_mutex); base::MessageLoop *gpuMessageLoop = gpu_message_loop(); - content::SyncPointManager *syncPointManager = sync_point_manager(); + gpu::SyncPointManager *syncPointManager = sync_point_manager(); Q_FOREACH (MailboxTexture *mailboxTexture, mailboxesToFetch) { m_numPendingSyncPoints++; @@ -444,6 +444,20 @@ void DelegatedFrameNode::preprocess() } } +static YUVVideoMaterial::ColorSpace toQt(cc::YUVVideoDrawQuad::ColorSpace color_space) +{ + switch (color_space) { + case cc::YUVVideoDrawQuad::REC_601: + return YUVVideoMaterial::REC_601; + case cc::YUVVideoDrawQuad::REC_709: + return YUVVideoMaterial::REC_709; + case cc::YUVVideoDrawQuad::JPEG: + return YUVVideoMaterial::JPEG; + } + Q_UNREACHABLE(); + return YUVVideoMaterial::REC_601; +} + void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, cc::ReturnedResourceArray *resourcesToRelease, RenderWidgetHostViewQtDelegate *apiDelegate) { m_chromiumCompositorData = chromiumCompositorData; @@ -560,7 +574,7 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, ResourceHolder *resource = findAndHoldResource(tquad->resource_id, resourceCandidates); QSGSimpleTextureNode *textureNode = new QSGSimpleTextureNode; - textureNode->setTextureCoordinatesTransform(tquad->flipped ? QSGSimpleTextureNode::MirrorVertically : QSGSimpleTextureNode::NoTransform); + textureNode->setTextureCoordinatesTransform(tquad->y_flipped ? QSGSimpleTextureNode::MirrorVertically : QSGSimpleTextureNode::NoTransform); textureNode->setRect(toQt(quad->rect)); textureNode->setFiltering(resource->transferableResource().filter == GL_LINEAR ? QSGTexture::Linear : QSGTexture::Nearest); textureNode->setTexture(initAndHoldTexture(resource, quad->ShouldDrawWithBlending(), apiDelegate)); @@ -628,7 +642,9 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, initAndHoldTexture(yResource, quad->ShouldDrawWithBlending()), initAndHoldTexture(uResource, quad->ShouldDrawWithBlending()), initAndHoldTexture(vResource, quad->ShouldDrawWithBlending()), - aResource ? initAndHoldTexture(aResource, quad->ShouldDrawWithBlending()) : 0, toQt(vquad->tex_coord_rect)); + aResource ? initAndHoldTexture(aResource, quad->ShouldDrawWithBlending()) : 0, + toQt(vquad->ya_tex_coord_rect), toQt(vquad->uv_tex_coord_rect), + toQt(vquad->ya_tex_size), toQt(vquad->uv_tex_size), toQt(vquad->color_space)); videoNode->setRect(toQt(quad->rect)); currentLayerChain->appendChildNode(videoNode); break; diff --git a/src/core/dev_tools_http_handler_delegate_qt.cpp b/src/core/dev_tools_http_handler_delegate_qt.cpp index 964d6ad38..2afd75e6e 100644 --- a/src/core/dev_tools_http_handler_delegate_qt.cpp +++ b/src/core/dev_tools_http_handler_delegate_qt.cpp @@ -49,9 +49,11 @@ #include "base/files/file_path.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "components/devtools_discovery/devtools_discovery_manager.h" +#include "components/devtools_discovery/devtools_target_descriptor.h" +#include "components/devtools_http_handler/devtools_http_handler.h" #include "content/public/browser/devtools_agent_host.h" -#include "content/public/browser/devtools_http_handler.h" -#include "content/public/browser/devtools_target.h" +#include "content/public/browser/devtools_frontend_host.h" #include "content/public/browser/favicon_status.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/render_view_host.h" @@ -59,14 +61,18 @@ #include "content/public/browser/web_contents_delegate.h" #include "content/public/common/content_switches.h" #include "net/base/ip_endpoint.h" +#include "net/base/net_errors.h" #include "net/socket/stream_listen_socket.h" #include "net/socket/tcp_server_socket.h" using namespace content; +using namespace devtools_discovery; +using namespace devtools_http_handler; namespace { const char kTargetTypePage[] = "page"; +const char kTargetTypeSharedWorker[] = "worker"; const char kTargetTypeServiceWorker[] = "service_worker"; const char kTargetTypeOther[] = "other"; @@ -74,15 +80,29 @@ class TCPServerSocketFactory : public DevToolsHttpHandler::ServerSocketFactory { public: TCPServerSocketFactory(const std::string& address, int port, int backlog) - : DevToolsHttpHandler::ServerSocketFactory(address, port, backlog) {} + : m_address(address), m_port(port), m_backlog(backlog) + {} private: - scoped_ptr<net::ServerSocket> Create() const override { - return scoped_ptr<net::ServerSocket>(new net::TCPServerSocket(NULL, net::NetLog::Source())); - } - DISALLOW_COPY_AND_ASSIGN(TCPServerSocketFactory); + scoped_ptr<net::ServerSocket> CreateForHttpServer() override { + scoped_ptr<net::ServerSocket> socket(new net::TCPServerSocket(nullptr, net::NetLog::Source())); + if (socket->ListenWithAddressAndPort(m_address, m_port, m_backlog) != net::OK) + return scoped_ptr<net::ServerSocket>(); + + return socket; + } + + const std::string m_address; + int m_port; + int m_backlog; + DISALLOW_COPY_AND_ASSIGN(TCPServerSocketFactory); }; -class Target : public content::DevToolsTarget { +class DevToolsDiscoveryProviderQt : public DevToolsDiscoveryManager::Provider { +public: + DevToolsTargetDescriptor::List GetDescriptors() override; +}; + +class Target : public DevToolsTargetDescriptor { public: explicit Target(scoped_refptr<DevToolsAgentHost> agent_host); @@ -92,6 +112,8 @@ public: switch (agent_host_->GetType()) { case DevToolsAgentHost::TYPE_WEB_CONTENTS: return kTargetTypePage; + case DevToolsAgentHost::TYPE_SHARED_WORKER: + return kTargetTypeSharedWorker; case DevToolsAgentHost::TYPE_SERVICE_WORKER: return kTargetTypeServiceWorker; default: @@ -141,17 +163,40 @@ bool Target::Close() const { return agent_host_->Close(); } +DevToolsTargetDescriptor::List DevToolsDiscoveryProviderQt::GetDescriptors() +{ + DevToolsTargetDescriptor::List targets; + for (const auto& agent_host : DevToolsAgentHost::GetOrCreateAll()) { + targets.push_back(new Target(agent_host)); + } + return targets; +} + } // namespace namespace QtWebEngineCore { +scoped_ptr<DevToolsHttpHandler> createDevToolsHttpHandler() +{ + DevToolsHttpHandlerDelegateQt *delegate = new DevToolsHttpHandlerDelegateQt(); + if (!delegate->isValid()) { + delete delegate; + return nullptr; + } + scoped_ptr<DevToolsHttpHandler::ServerSocketFactory> factory(new TCPServerSocketFactory(delegate->bindAddress().toStdString(), delegate->port(), 1)); + // Ownership of the delegate is taken over the devtools http handler. + scoped_ptr<DevToolsHttpHandler> handler(new DevToolsHttpHandler(factory.Pass(), std::string(), delegate, base::FilePath(), base::FilePath(), std::string(), std::string())); + DevToolsDiscoveryManager::GetInstance()->AddProvider(scoped_ptr<DevToolsDiscoveryManager::Provider>(new DevToolsDiscoveryProviderQt())); + return handler; +} + DevToolsHttpHandlerDelegateQt::DevToolsHttpHandlerDelegateQt() - : m_devtoolsHttpHandler(0) - , m_bindAddress(QLatin1String("127.0.0.1")) + : m_bindAddress(QLatin1String("127.0.0.1")) , m_port(0) + , m_valid(false) { const QString inspectorEnv = QString::fromUtf8(qgetenv("QTWEBENGINE_REMOTE_DEBUGGING")); - const CommandLine &commandLine = *CommandLine::ForCurrentProcess(); + const base::CommandLine &commandLine = *base::CommandLine::ForCurrentProcess(); QString portStr; if (commandLine.HasSwitch(switches::kRemoteDebuggingPort)) { @@ -166,26 +211,16 @@ DevToolsHttpHandlerDelegateQt::DevToolsHttpHandlerDelegateQt() } else return; - bool ok = false; - m_port = portStr.toInt(&ok); - if (ok && m_port > 0 && m_port < 65535) { - scoped_ptr<content::DevToolsHttpHandler::ServerSocketFactory> factory(new TCPServerSocketFactory(m_bindAddress.toStdString(), m_port, 1)); - m_devtoolsHttpHandler = DevToolsHttpHandler::Start(factory.Pass(), std::string(), this, base::FilePath()); - } else + m_port = portStr.toInt(&m_valid); + m_valid = m_valid && m_port > 0 && m_port < 65535; + if (!m_valid) qWarning("Invalid port given for the inspector server \"%s\". Examples of valid input: \"12345\" or \"192.168.2.14:12345\" (with the address of one of this host's network interface).", qPrintable(portStr)); } -DevToolsHttpHandlerDelegateQt::~DevToolsHttpHandlerDelegateQt() -{ - // Stop() takes care of deleting the DevToolsHttpHandler. - if (m_devtoolsHttpHandler) - m_devtoolsHttpHandler->Stop(); -} - -void DevToolsHttpHandlerDelegateQt::Initialized(const net::IPEndPoint& ip_address) +void DevToolsHttpHandlerDelegateQt::Initialized(const net::IPEndPoint *ip_address) { - if (ip_address.address().size()) { - QString addressAndPort = QString::fromStdString(ip_address.ToString()); + if (ip_address && ip_address->address().size()) { + QString addressAndPort = QString::fromStdString(ip_address->ToString()); qWarning("Remote debugging server started successfully. Try pointing a Chromium-based browser to http://%s", qPrintable(addressAndPort)); } else qWarning("Couldn't start the inspector server on bind address \"%s\" and port \"%d\". In case of invalid input, try something like: \"12345\" or \"192.168.2.14:12345\" (with the address of one of this host's interface).", qPrintable(m_bindAddress), m_port); @@ -203,42 +238,19 @@ std::string DevToolsHttpHandlerDelegateQt::GetDiscoveryPageHTML() return html; } -bool DevToolsHttpHandlerDelegateQt::BundlesFrontendResources() -{ - return true; -} - -base::FilePath DevToolsHttpHandlerDelegateQt::GetDebugFrontendDir() -{ - return base::FilePath(); -} - -scoped_ptr<net::StreamListenSocket> DevToolsHttpHandlerDelegateQt::CreateSocketForTethering(net::StreamListenSocket::Delegate* delegate, std::string* name) -{ - return scoped_ptr<net::StreamListenSocket>(); -} - -base::DictionaryValue* DevToolsManagerDelegateQt::HandleCommand(DevToolsAgentHost *, base::DictionaryValue *) { - return 0; -} - -std::string DevToolsManagerDelegateQt::GetPageThumbnailData(const GURL& url) +std::string DevToolsHttpHandlerDelegateQt::GetPageThumbnailData(const GURL& url) { return std::string(); } -scoped_ptr<DevToolsTarget> DevToolsManagerDelegateQt::CreateNewTarget(const GURL &) +std::string DevToolsHttpHandlerDelegateQt::GetFrontendResource(const std::string &path) { - return scoped_ptr<DevToolsTarget>(); + return content::DevToolsFrontendHost::GetFrontendResource(path).as_string(); } -void DevToolsManagerDelegateQt::EnumerateTargets(TargetCallback callback) +base::DictionaryValue* DevToolsManagerDelegateQt::HandleCommand(DevToolsAgentHost *, base::DictionaryValue *) { - TargetList targets; - for (const auto& agent_host : DevToolsAgentHost::GetOrCreateAll()) { - targets.push_back(new Target(agent_host)); - } - callback.Run(targets); + return 0; } } //namespace QtWebEngineCore diff --git a/src/core/dev_tools_http_handler_delegate_qt.h b/src/core/dev_tools_http_handler_delegate_qt.h index 902e99507..b998359fd 100644 --- a/src/core/dev_tools_http_handler_delegate_qt.h +++ b/src/core/dev_tools_http_handler_delegate_qt.h @@ -37,43 +37,43 @@ #ifndef DEV_TOOLS_HTTP_HANDLER_DELEGATE_QT_H #define DEV_TOOLS_HTTP_HANDLER_DELEGATE_QT_H -#include "content/public/browser/devtools_http_handler_delegate.h" +#include "components/devtools_http_handler/devtools_http_handler_delegate.h" #include "content/public/browser/devtools_manager_delegate.h" +#include "net/socket/stream_listen_socket.h" #include <QString> #include <QtCore/qcompilerdetection.h> // needed for Q_DECL_OVERRIDE -namespace net { -class StreamListenSocket; -} - namespace content { class BrowserContext; +} + +namespace devtools_http_handler { class DevToolsHttpHandler; -class RenderViewHost; } namespace QtWebEngineCore { -class DevToolsHttpHandlerDelegateQt : public content::DevToolsHttpHandlerDelegate { -public: +scoped_ptr<devtools_http_handler::DevToolsHttpHandler> createDevToolsHttpHandler(); +class DevToolsHttpHandlerDelegateQt : public devtools_http_handler::DevToolsHttpHandlerDelegate { +public: DevToolsHttpHandlerDelegateQt(); - virtual ~DevToolsHttpHandlerDelegateQt(); - // content::DevToolsHttpHandlerDelegate Overrides - virtual void Initialized(const net::IPEndPoint &ip_address) Q_DECL_OVERRIDE; - virtual std::string GetDiscoveryPageHTML() Q_DECL_OVERRIDE; - virtual bool BundlesFrontendResources() Q_DECL_OVERRIDE; - virtual base::FilePath GetDebugFrontendDir() Q_DECL_OVERRIDE; - // Requests the list of all inspectable targets. - // The caller gets the ownership of the returned targets. - virtual scoped_ptr<net::StreamListenSocket> CreateSocketForTethering(net::StreamListenSocket::Delegate *delegate, std::string *name) Q_DECL_OVERRIDE; + bool isValid() const { return m_valid; } + QString bindAddress() const { return m_bindAddress; } + int port() const { return m_port; } + + // devtools_http_handler::DevToolsHttpHandlerDelegate Overrides + void Initialized(const net::IPEndPoint *ip_address) Q_DECL_OVERRIDE; + std::string GetDiscoveryPageHTML() Q_DECL_OVERRIDE; + std::string GetFrontendResource(const std::string&) Q_DECL_OVERRIDE; + std::string GetPageThumbnailData(const GURL &url) Q_DECL_OVERRIDE; private: - content::DevToolsHttpHandler *m_devtoolsHttpHandler; QString m_bindAddress; int m_port; + bool m_valid; }; class DevToolsManagerDelegateQt : public content::DevToolsManagerDelegate { @@ -81,9 +81,6 @@ public: void Inspect(content::BrowserContext *browser_context, content::DevToolsAgentHost *agent_host) Q_DECL_OVERRIDE { } void DevToolsAgentStateChanged(content::DevToolsAgentHost *agent_host, bool attached) Q_DECL_OVERRIDE { } base::DictionaryValue *HandleCommand(content::DevToolsAgentHost *agent_host, base::DictionaryValue *command) Q_DECL_OVERRIDE; - scoped_ptr<content::DevToolsTarget> CreateNewTarget(const GURL &url) Q_DECL_OVERRIDE; - void EnumerateTargets(TargetCallback callback) Q_DECL_OVERRIDE; - std::string GetPageThumbnailData(const GURL &url) Q_DECL_OVERRIDE; }; } // namespace QtWebEngineCore diff --git a/src/core/doc/qtwebenginecore.qdocconf b/src/core/doc/qtwebenginecore.qdocconf new file mode 100644 index 000000000..491447706 --- /dev/null +++ b/src/core/doc/qtwebenginecore.qdocconf @@ -0,0 +1,32 @@ +include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf) + +project = QtWebEngineCore +description = Qt WebEngineCore Reference Documentation +version = $QT_VERSION + +qhp.projects = QtWebEngineCore + +qhp.QtWebEngineCore.file = qtwebenginecore.qhp +qhp.QtWebEngineCore.namespace = org.qt-project.qtwebenginecore.$QT_VERSION_TAG +qhp.QtWebEngineCore.virtualFolder = qtwebenginecore +qhp.QtWebEngineCore.indexTitle = Qt WebEngine Core +qhp.QtWebEngineCore.indexRoot = + +qhp.QtWebEngineCore.filterAttributes = qtwebenginecore $QT_VERSION qtrefdoc +qhp.QtWebEngineCore.customFilters.Qt.name = QtWebEngineCore $QT_VERSION +qhp.QtWebEngineCore.customFilters.Qt.filterAttributes = qtwebenginecore $QT_VERSION +qhp.QtWebEngineCore.subprojects = classes +qhp.QtWebEngineCore.subprojects.classes.title = C++ Classes +qhp.QtWebEngineCore.subprojects.classes.indexTitle = Qt WebEngine Core C++ Classes +qhp.QtWebEngineCore.subprojects.classes.selectors = class fake:headerfile +qhp.QtWebEngineCore.subprojects.classes.sortPages = true + +depends += qtcore qtdoc qmake + +headerdirs += ../api +sourcedirs += ../api src + +exampledirs += snippets + +navigation.landingpage = "Qt WebEngine Core" +navigation.cppclassespage = "Qt WebEngine Core C++ Class Types" diff --git a/src/core/doc/snippets/qtwebenginecore_build_snippet.qdoc b/src/core/doc/snippets/qtwebenginecore_build_snippet.qdoc new file mode 100644 index 000000000..4806359c9 --- /dev/null +++ b/src/core/doc/snippets/qtwebenginecore_build_snippet.qdoc @@ -0,0 +1,8 @@ +//! [0] +QT += webenginecore +//! [0] + + +//! [1] +#include <QtWebEngineCore> +//! [1] diff --git a/src/core/doc/src/qtwebenginecore.qdoc b/src/core/doc/src/qtwebenginecore.qdoc new file mode 100644 index 000000000..a690d3f0e --- /dev/null +++ b/src/core/doc/src/qtwebenginecore.qdoc @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +/*! + \module QtWebEngineCore + \title Qt WebEngine Core C++ Classes + \brief Provides public API shared by both QtWebEngine and QtWebEngineWidgets + \since 5.6 + + To include the definitions of the module's classes, use the + following directive: + + \snippet qtwebenginecore_build_snippet.qdoc 1 + + If you use qmake to build your projects, Qt WebEngine Core is usually + indirectly included through the \l[QtWebEngine]{Qt WebEngine} or + \l[QtWebEngineWidgets]{Qt WebEngine Widgets} modules. +*/ + +/*! + \page qtwebenginecore-index.html + \title Qt WebEngine Core + \ingroup modules + + \brief Common API shared by both Qt WebEngine and Qt WebEngine Widgets. + + Qt WebEngine Core provides API shared by both Qt WebEngine and + Qt WebEngine Widgets. + + + \section1 License Information + This is a snapshot of the integration of Chromium into Qt. + + Qt Commercial Edition licensees that wish to distribute applications that + use the Qt WebEngine module need to be aware of their obligations under the + GNU Library General Public License (LGPLv2). + + Developers using the Open Source Edition can choose to redistribute + the module under the GNU LGPLv3 or GPLv2 and up. + + \legalese + + Chromium is licensed under the following license: + + Copyright (c) 2013 The Chromium Authors. 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. + + \endlegalese +*/ diff --git a/src/core/file_picker_controller.cpp b/src/core/file_picker_controller.cpp new file mode 100644 index 000000000..18896c6b4 --- /dev/null +++ b/src/core/file_picker_controller.cpp @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "file_picker_controller.h" +#include "type_conversion.h" +#include "content/browser/renderer_host/render_view_host_impl.h" +#include "content/browser/web_contents/web_contents_impl.h" + +#include <QFileInfo> +#include <QDir> +#include <QVariant> +#include <QStringList> + +namespace QtWebEngineCore { + +FilePickerController::FilePickerController(FileChooserMode mode, content::WebContents *contents, const QString &defaultFileName, const QStringList &acceptedMimeTypes, QObject *parent) + : QObject(parent) + , m_defaultFileName(defaultFileName) + , m_acceptedMimeTypes(acceptedMimeTypes) + , m_contents(contents) + , m_mode(mode) +{ +} + +void FilePickerController::accepted(const QStringList &files) +{ + FilePickerController::filesSelectedInChooser(files, m_contents); +} + +void FilePickerController::accepted(const QVariant &files) +{ + QStringList stringList; + + if (files.canConvert(QVariant::StringList)) { + stringList = files.toStringList(); + } else if (files.canConvert<QList<QUrl> >()) { + Q_FOREACH (const QUrl &url, files.value<QList<QUrl> >()) + stringList.append(url.toLocalFile()); + } else { + qWarning("An unhandled type '%s' was provided in FilePickerController::accepted(QVariant)", files.typeName()); + } + + FilePickerController::filesSelectedInChooser(stringList, m_contents); +} + +void FilePickerController::rejected() +{ + FilePickerController::filesSelectedInChooser(QStringList(), m_contents); +} + +static QStringList listRecursively(const QDir &dir) +{ + QStringList ret; + QFileInfoList infoList(dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot | QDir::Hidden)); + Q_FOREACH (const QFileInfo &fileInfo, infoList) { + if (fileInfo.isDir()) { + ret.append(fileInfo.absolutePath() + QStringLiteral("/.")); // Match chromium's behavior. See chrome/browser/file_select_helper.cc + ret.append(listRecursively(QDir(fileInfo.absoluteFilePath()))); + } else + ret.append(fileInfo.absoluteFilePath()); + } + return ret; +} + +ASSERT_ENUMS_MATCH(FilePickerController::Open, content::FileChooserParams::Open) +ASSERT_ENUMS_MATCH(FilePickerController::OpenMultiple, content::FileChooserParams::OpenMultiple) +ASSERT_ENUMS_MATCH(FilePickerController::UploadFolder, content::FileChooserParams::UploadFolder) +ASSERT_ENUMS_MATCH(FilePickerController::Save, content::FileChooserParams::Save) + +void FilePickerController::filesSelectedInChooser(const QStringList &filesList, content::WebContents *contents) +{ + content::RenderViewHost *rvh = contents->GetRenderViewHost(); + Q_ASSERT(rvh); + QStringList files(filesList); + if (this->m_mode == UploadFolder && !filesList.isEmpty() + && QFileInfo(filesList.first()).isDir()) // Enumerate the directory + files = listRecursively(QDir(filesList.first())); + rvh->FilesSelectedInChooser(toVector<content::FileChooserFileInfo>(files), static_cast<content::FileChooserParams::Mode>(this->m_mode)); +} + +QStringList FilePickerController::acceptedMimeTypes() +{ + return m_acceptedMimeTypes; +} + +FilePickerController::FileChooserMode FilePickerController::mode() +{ + return m_mode; +} + +QString FilePickerController::defaultFileName() +{ + return m_defaultFileName; +} + +} // namespace diff --git a/src/core/file_picker_controller.h b/src/core/file_picker_controller.h new file mode 100644 index 000000000..347dd11ef --- /dev/null +++ b/src/core/file_picker_controller.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef FILE_PICKER_CONTROLLER_H +#define FILE_PICKER_CONTROLLER_H + +#include "qtwebenginecoreglobal.h" +#include <QObject> +#include <QStringList> + +namespace content { + class WebContents; +} + +namespace QtWebEngineCore { + +class QWEBENGINE_EXPORT FilePickerController : public QObject { + Q_OBJECT +public: + enum FileChooserMode { + Open, + OpenMultiple, + UploadFolder, + Save + }; + + FilePickerController(FileChooserMode mode, content::WebContents *contents, const QString &defaultFileName, const QStringList &acceptedMimeTypes, QObject * = 0); + QStringList acceptedMimeTypes(); + QString defaultFileName(); + FileChooserMode mode(); + void filesSelectedInChooser(const QStringList &filesList, content::WebContents *contents); + +public Q_SLOTS: + void accepted(const QStringList &files); + void accepted(const QVariant &files); + void rejected(); + +private: + QString m_defaultFileName; + QStringList m_acceptedMimeTypes; + content::WebContents *m_contents; + FileChooserMode m_mode; + +}; + +} // namespace + +#endif // FILE_PICKER_CONTROLLER_H diff --git a/src/core/gl_surface_qt.cpp b/src/core/gl_surface_qt.cpp index 584bdc227..c905688ce 100644 --- a/src/core/gl_surface_qt.cpp +++ b/src/core/gl_surface_qt.cpp @@ -44,7 +44,7 @@ #include <QGuiApplication> #include "gl_context_qt.h" -#include "qtwebenginecoreglobal.h" +#include "qtwebenginecoreglobal_p.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" @@ -533,6 +533,22 @@ GLSurface::CreateViewGLSurface(gfx::AcceleratedWidget window) return NULL; } +std::string DriverEGL::GetPlatformExtensions() +{ +#if defined(USE_X11) + EGLNativeDisplayType nativeDisplay = reinterpret_cast<EGLNativeDisplayType>(GLContextHelper::getXDisplay()); + EGLDisplay display = eglGetDisplay(nativeDisplay); +#else + EGLDisplay display = GLContextHelper::getEGLDisplay(); +#endif + if (display == EGL_NO_DISPLAY) + return ""; + + DCHECK(g_driver_egl.fn.eglQueryStringFn); + const char* str = g_driver_egl.fn.eglQueryStringFn(display, EGL_EXTENSIONS); + return str ? std::string(str) : ""; +} + } // namespace gfx namespace content { diff --git a/src/core/gl_surface_qt.h b/src/core/gl_surface_qt.h index 21c46e699..4b5da207e 100644 --- a/src/core/gl_surface_qt.h +++ b/src/core/gl_surface_qt.h @@ -39,7 +39,7 @@ #ifndef GL_SURFACE_QT_H_ #define GL_SURFACE_QT_H_ -#include "ui/gfx/size.h" +#include "ui/gfx/geometry/size.h" #include "ui/gl/gl_surface.h" #include <QtCore/qcompilerdetection.h> // Needed for Q_DECL_OVERRIDE diff --git a/src/core/gyp_run.pro b/src/core/gyp_run.pro index 3f631302c..bb19a679d 100644 --- a/src/core/gyp_run.pro +++ b/src/core/gyp_run.pro @@ -85,7 +85,7 @@ cross_compile { contains(QT_ARCH, "x86_64"): GYP_ARGS += "-D target_arch=x64" contains(QT_ARCH, "i386"): GYP_ARGS += "-D target_arch=ia32" -contains(WEBENGINE_CONFIG, proprietary_codecs): GYP_ARGS += "-Dproprietary_codecs=1 -Dffmpeg_branding=Chrome -Duse_system_ffmpeg=0" +contains(WEBENGINE_CONFIG, use_proprietary_codecs): GYP_ARGS += "-Dproprietary_codecs=1 -Dffmpeg_branding=Chrome -Duse_system_ffmpeg=0" !contains(QT_CONFIG, qt_framework): contains(QT_CONFIG, private_tests) { GYP_ARGS += "-D qt_install_data=\"$$[QT_INSTALL_DATA/get]\"" diff --git a/src/core/javascript_dialog_manager_qt.h b/src/core/javascript_dialog_manager_qt.h index 4682ce5b8..8bf7ac6b9 100644 --- a/src/core/javascript_dialog_manager_qt.h +++ b/src/core/javascript_dialog_manager_qt.h @@ -66,8 +66,7 @@ public: const content::JavaScriptDialogManager::DialogClosedCallback &callback) Q_DECL_OVERRIDE { Q_UNUSED(messageText); Q_UNUSED(isReload); Q_UNUSED(callback); } virtual bool HandleJavaScriptDialog(content::WebContents *, bool accept, const base::string16 *promptOverride) Q_DECL_OVERRIDE; virtual void CancelActiveAndPendingDialogs(content::WebContents *contents) Q_DECL_OVERRIDE { takeDialogForContents(contents); } - virtual void WebContentsDestroyed(content::WebContents *contents) Q_DECL_OVERRIDE { takeDialogForContents(contents); } - + virtual void ResetDialogState(content::WebContents *contents) Q_DECL_OVERRIDE { takeDialogForContents(contents); } void runDialogForContents(content::WebContents *, WebContentsAdapterClient::JavascriptDialogType, const QString &messageText, const QString &defaultPrompt , const QUrl &,const content::JavaScriptDialogManager::DialogClosedCallback &callback, const QString &title = QString()); diff --git a/src/core/media_capture_devices_dispatcher.cpp b/src/core/media_capture_devices_dispatcher.cpp index 6866afc41..605a17948 100644 --- a/src/core/media_capture_devices_dispatcher.cpp +++ b/src/core/media_capture_devices_dispatcher.cpp @@ -91,9 +91,8 @@ scoped_ptr<content::MediaStreamUI> getDevicesForDesktopCapture(content::MediaStr devices.push_back(content::MediaStreamDevice( content::MEDIA_DESKTOP_VIDEO_CAPTURE, mediaId.ToString(), "Screen")); if (captureAudio) { - // Use the special loopback device ID for system audio capture. devices.push_back(content::MediaStreamDevice( - content::MEDIA_LOOPBACK_AUDIO_CAPTURE, + content::MEDIA_DESKTOP_AUDIO_CAPTURE, media::AudioManagerBase::kLoopbackInputDeviceId, "System Audio")); } @@ -225,7 +224,7 @@ void MediaCaptureDevicesDispatcher::processMediaAccessRequest(WebContentsAdapter if (request.video_type == content::MEDIA_TAB_VIDEO_CAPTURE || request.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE) return; - if (request.video_type == content::MEDIA_DESKTOP_VIDEO_CAPTURE || request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE) + if (request.video_type == content::MEDIA_DESKTOP_VIDEO_CAPTURE || request.audio_type == content::MEDIA_DESKTOP_AUDIO_CAPTURE) // It's still unclear what to make of screen capture. We can rely on existing javascript dialog infrastructure // to experiment with this without exposing it through our API yet. processDesktopCaptureAccessRequest(webContents, request, callback); @@ -279,7 +278,7 @@ void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content:: // Audio is only supported for screen capture streams. bool capture_audio = (mediaId.type == content::DesktopMediaID::TYPE_SCREEN && - request.audio_type == content::MEDIA_LOOPBACK_AUDIO_CAPTURE); + request.audio_type == content::MEDIA_DESKTOP_AUDIO_CAPTURE); ui = getDevicesForDesktopCapture( devices, mediaId, capture_audio, true, diff --git a/src/core/network_delegate_qt.cpp b/src/core/network_delegate_qt.cpp index 4e726fec8..5af781007 100644 --- a/src/core/network_delegate_qt.cpp +++ b/src/core/network_delegate_qt.cpp @@ -36,31 +36,37 @@ #include "network_delegate_qt.h" +#include "browser_context_adapter.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/resource_request_details.h" #include "content/public/browser/resource_request_info.h" +#include "cookie_monster_delegate_qt.h" #include "ui/base/page_transition_types.h" +#include "url_request_context_getter_qt.h" #include "net/base/load_flags.h" #include "net/url_request/url_request.h" +#include "qwebengineurlrequestinfo.h" +#include "qwebengineurlrequestinfo_p.h" +#include "qwebengineurlrequestinterceptor.h" #include "type_conversion.h" #include "web_contents_adapter_client.h" #include "web_contents_view_qt.h" namespace QtWebEngineCore { -int pageTransitionToNavigationType(ui::PageTransition transition) +static int pageTransitionToNavigationType(ui::PageTransition transition) { int32 qualifier = ui::PageTransitionGetQualifier(transition); if (qualifier & ui::PAGE_TRANSITION_FORWARD_BACK) return WebContentsAdapterClient::BackForwardNavigation; - ui::PageTransition stippedTransition = ui::PageTransitionStripQualifier(transition); + ui::PageTransition strippedTransition = ui::PageTransitionStripQualifier(transition); - switch (stippedTransition) { + switch (strippedTransition) { case ui::PAGE_TRANSITION_LINK: - return WebContentsAdapterClient::LinkClickedNavigation; + return WebContentsAdapterClient::LinkNavigation; case ui::PAGE_TRANSITION_TYPED: return WebContentsAdapterClient::TypedNavigation; case ui::PAGE_TRANSITION_FORM_SUBMIT: @@ -72,29 +78,68 @@ int pageTransitionToNavigationType(ui::PageTransition transition) } } -int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, const net::CompletionCallback &callback, GURL *) +NetworkDelegateQt::NetworkDelegateQt(URLRequestContextGetterQt *requestContext) + : m_requestContextGetter(requestContext) +{ +} + +int NetworkDelegateQt::OnBeforeURLRequest(net::URLRequest *request, const net::CompletionCallback &callback, GURL *newUrl) { Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); - const content::ResourceRequestInfo *info = content::ResourceRequestInfo::ForRequest(request); - if (!info) + Q_ASSERT(m_requestContextGetter); + Q_ASSERT(m_requestContextGetter->m_browserContext); + + const content::ResourceRequestInfo *resourceInfo = content::ResourceRequestInfo::ForRequest(request); + + content::ResourceType resourceType = content::RESOURCE_TYPE_LAST_TYPE; + int navigationType = QWebEngineUrlRequestInfo::NavigationTypeOther; + + if (resourceInfo) { + resourceType = resourceInfo->GetResourceType(); + navigationType = pageTransitionToNavigationType(resourceInfo->GetPageTransition()); + } + + const QUrl qUrl = toQt(request->url()); + + QWebEngineUrlRequestInterceptor* interceptor = m_requestContextGetter->m_browserContext->requestInterceptor(); + if (interceptor) { + QWebEngineUrlRequestInfoPrivate *infoPrivate = new QWebEngineUrlRequestInfoPrivate(static_cast<QWebEngineUrlRequestInfo::ResourceType>(resourceType) + , static_cast<QWebEngineUrlRequestInfo::NavigationType>(navigationType) + , qUrl + , QByteArray::fromStdString(request->method())); + QWebEngineUrlRequestInfo requestInfo(infoPrivate); + if (interceptor->interceptRequest(requestInfo)) { + int result = infoPrivate->shouldBlockRequest ? net::ERR_ABORTED : net::OK; + + if (qUrl != infoPrivate->url) + *newUrl = toGurl(infoPrivate->url); + + if (!infoPrivate->extraHeaders.isEmpty()) { + auto end = infoPrivate->extraHeaders.constEnd(); + for (auto header = infoPrivate->extraHeaders.constBegin(); header != end; ++header) + request->SetExtraRequestHeaderByName(header.key().toStdString(), header.value().toStdString(), /* overwrite */ true); + } + + return result; + } + } + + if (!resourceInfo) return net::OK; - content::ResourceType resourceType = info->GetResourceType(); int renderProcessId; int renderFrameId; // Only intercept MAIN_FRAME and SUB_FRAME with an associated render frame. - if (!content::IsResourceTypeFrame(resourceType) || !info->GetRenderFrameForRequest(request, &renderProcessId, &renderFrameId)) + if (!content::IsResourceTypeFrame(resourceType) || !resourceInfo->GetRenderFrameForRequest(request, &renderProcessId, &renderFrameId)) return net::OK; // Track active requests since |callback| and |new_url| are valid // only until OnURLRequestDestroyed is called for this request. m_activeRequests.insert(request); - int navigationType = pageTransitionToNavigationType(info->GetPageTransition()); - RequestParams params = { - toQt(request->url()), - info->IsMainFrame(), + qUrl, + resourceInfo->IsMainFrame(), navigationType, renderProcessId, renderFrameId @@ -172,4 +217,92 @@ void NetworkDelegateQt::NotifyNavigationRequestedOnUIThread(net::URLRequest *req ); } +bool NetworkDelegateQt::OnCanSetCookie(const net::URLRequest& request, + const std::string& cookie_line, + net::CookieOptions*) +{ + return true; +} + +void NetworkDelegateQt::OnResolveProxy(const GURL&, int, const net::ProxyService&, net::ProxyInfo*) +{ +} + +void NetworkDelegateQt::OnProxyFallback(const net::ProxyServer&, int) +{ +} + +int NetworkDelegateQt::OnBeforeSendHeaders(net::URLRequest*, const net::CompletionCallback&, net::HttpRequestHeaders*) +{ + return net::OK; +} + +void NetworkDelegateQt::OnBeforeSendProxyHeaders(net::URLRequest*, const net::ProxyInfo&, net::HttpRequestHeaders*) +{ +} + +void NetworkDelegateQt::OnSendHeaders(net::URLRequest*, const net::HttpRequestHeaders&) +{ +} + +int NetworkDelegateQt::OnHeadersReceived(net::URLRequest*, const net::CompletionCallback&, const net::HttpResponseHeaders*, scoped_refptr<net::HttpResponseHeaders>*, GURL*) +{ + return net::OK; +} + +void NetworkDelegateQt::OnBeforeRedirect(net::URLRequest*, const GURL&) +{ +} + +void NetworkDelegateQt::OnResponseStarted(net::URLRequest*) +{ +} + +void NetworkDelegateQt::OnRawBytesRead(const net::URLRequest&, int) +{ +} + +void NetworkDelegateQt::OnCompleted(net::URLRequest*, bool) +{ +} + +void NetworkDelegateQt::OnPACScriptError(int, const base::string16&) +{ +} + +net::NetworkDelegate::AuthRequiredResponse NetworkDelegateQt::OnAuthRequired(net::URLRequest*, const net::AuthChallengeInfo&, const AuthCallback&, net::AuthCredentials*) +{ + return AUTH_REQUIRED_RESPONSE_NO_ACTION; +} + +bool NetworkDelegateQt::OnCanGetCookies(const net::URLRequest&, const net::CookieList&) +{ + return true; +} + +bool NetworkDelegateQt::OnCanAccessFile(const net::URLRequest& request, const base::FilePath& path) const +{ + return true; +} + +bool NetworkDelegateQt::OnCanThrottleRequest(const net::URLRequest&) const +{ + return false; +} + +bool NetworkDelegateQt::OnCanEnablePrivacyMode(const GURL&, const GURL&) const +{ + return false; +} + +bool NetworkDelegateQt::OnFirstPartyOnlyCookieExperimentEnabled() const +{ + return false; +} + +bool NetworkDelegateQt::OnCancelURLRequestWithPolicyViolatingReferrerHeader(const net::URLRequest&, const GURL&, const GURL&) const +{ + return false; +} + } // namespace QtWebEngineCore diff --git a/src/core/network_delegate_qt.h b/src/core/network_delegate_qt.h index 4f4097fd3..1176f99d9 100644 --- a/src/core/network_delegate_qt.h +++ b/src/core/network_delegate_qt.h @@ -42,19 +42,16 @@ #include <QUrl> #include <QSet> -#include <QtCore/qcompilerdetection.h> // Needed for Q_DECL_OVERRIDE namespace QtWebEngineCore { +class URLRequestContextGetterQt; + class NetworkDelegateQt : public net::NetworkDelegate { + QSet<net::URLRequest *> m_activeRequests; + URLRequestContextGetterQt *m_requestContextGetter; public: - NetworkDelegateQt() {} - virtual ~NetworkDelegateQt() {} - - // net::NetworkDelegate implementation - virtual int OnBeforeURLRequest(net::URLRequest* request, const net::CompletionCallback& callback, GURL* new_url) Q_DECL_OVERRIDE; - virtual void OnURLRequestDestroyed(net::URLRequest* request) Q_DECL_OVERRIDE; - virtual bool OnCanAccessFile(const net::URLRequest& request, const base::FilePath& path) const Q_DECL_OVERRIDE { return true; } + NetworkDelegateQt(URLRequestContextGetterQt *requestContext); struct RequestParams { QUrl url; @@ -72,7 +69,28 @@ public: int navigationRequestAction, const net::CompletionCallback &callback); - QSet<net::URLRequest *> m_activeRequests; + // net::NetworkDelegate implementation + virtual int OnBeforeURLRequest(net::URLRequest* request, const net::CompletionCallback& callback, GURL* newUrl) override; + virtual void OnURLRequestDestroyed(net::URLRequest* request) override; + virtual bool OnCanSetCookie(const net::URLRequest&, const std::string&, net::CookieOptions*) override; + virtual void OnResolveProxy(const GURL&, int, const net::ProxyService&, net::ProxyInfo*) override; + virtual void OnProxyFallback(const net::ProxyServer&, int) override; + virtual int OnBeforeSendHeaders(net::URLRequest*, const net::CompletionCallback&, net::HttpRequestHeaders*) override; + virtual void OnBeforeSendProxyHeaders(net::URLRequest*, const net::ProxyInfo&, net::HttpRequestHeaders*) override; + virtual void OnSendHeaders(net::URLRequest*, const net::HttpRequestHeaders&) override; + virtual int OnHeadersReceived(net::URLRequest*, const net::CompletionCallback&, const net::HttpResponseHeaders*, scoped_refptr<net::HttpResponseHeaders>*, GURL*) override; + virtual void OnBeforeRedirect(net::URLRequest*, const GURL&) override; + virtual void OnResponseStarted(net::URLRequest*) override; + virtual void OnRawBytesRead(const net::URLRequest&, int) override; + virtual void OnCompleted(net::URLRequest*, bool) override; + virtual void OnPACScriptError(int, const base::string16&) override; + virtual net::NetworkDelegate::AuthRequiredResponse OnAuthRequired(net::URLRequest*, const net::AuthChallengeInfo&, const AuthCallback&, net::AuthCredentials*) override; + virtual bool OnCanGetCookies(const net::URLRequest&, const net::CookieList&) override; + virtual bool OnCanAccessFile(const net::URLRequest& request, const base::FilePath& path) const override; + virtual bool OnCanThrottleRequest(const net::URLRequest&) const override; + virtual bool OnCanEnablePrivacyMode(const GURL&, const GURL&) const override; + virtual bool OnFirstPartyOnlyCookieExperimentEnabled() const override; + virtual bool OnCancelURLRequestWithPolicyViolatingReferrerHeader(const net::URLRequest&, const GURL&, const GURL&) const override; }; } // namespace QtWebEngineCore diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp new file mode 100644 index 000000000..865874fe6 --- /dev/null +++ b/src/core/permission_manager_qt.cpp @@ -0,0 +1,207 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "permission_manager_qt.h" + +#include "content/public/browser/permission_type.h" +#include "content/public/browser/web_contents.h" + +#include "type_conversion.h" +#include "web_contents_delegate_qt.h" + +namespace QtWebEngineCore { + +BrowserContextAdapter::PermissionType toQt(content::PermissionType type) +{ + switch (type) { + case content::PermissionType::GEOLOCATION: + return BrowserContextAdapter::GeolocationPermission; + case content::PermissionType::NOTIFICATIONS: + case content::PermissionType::MIDI_SYSEX: + case content::PermissionType::PUSH_MESSAGING: + case content::PermissionType::PROTECTED_MEDIA_IDENTIFIER: + case content::PermissionType::NUM: + break; + } + return BrowserContextAdapter::UnsupportedPermission; +} + +PermissionManagerQt::PermissionManagerQt(BrowserContextAdapter *contextAdapter) + : m_contextAdapter(contextAdapter) + , m_subscriberCount(0) +{ +} + +PermissionManagerQt::~PermissionManagerQt() +{ +} + +void PermissionManagerQt::permissionRequestReply(const QUrl &origin, BrowserContextAdapter::PermissionType type, bool reply) +{ + QPair<QUrl, BrowserContextAdapter::PermissionType> key(origin, type); + m_permissions[key] = reply; + content::PermissionStatus status = reply ? content::PERMISSION_STATUS_GRANTED : content::PERMISSION_STATUS_DENIED; + auto it = m_requests.begin(); + const auto end = m_requests.end(); + while (it != end) { + if (it->origin == origin && it->type == type) { + it->callback.Run(status); + it = m_requests.erase(it); + } else + ++it; + } + Q_FOREACH (const Subscriber &subscriber, m_subscribers) { + if (subscriber.origin == origin && subscriber.type == type) + subscriber.callback.Run(status); + } +} + +void PermissionManagerQt::RequestPermission(content::PermissionType permission, + content::WebContents* web_contents, + int request_id, + const GURL& requesting_origin, + bool user_gesture, + const base::Callback<void(content::PermissionStatus)>& callback) +{ + Q_UNUSED(user_gesture); + BrowserContextAdapter::PermissionType permissionType = toQt(permission); + if (permissionType == BrowserContextAdapter::UnsupportedPermission) { + callback.Run(content::PERMISSION_STATUS_DENIED); + return; + } + + WebContentsDelegateQt* contentsDelegate = static_cast<WebContentsDelegateQt*>(web_contents->GetDelegate()); + Q_ASSERT(contentsDelegate); + Request request = { + request_id, + permissionType, + toQt(requesting_origin), + callback + }; + m_requests.append(request); + if (permissionType == BrowserContextAdapter::GeolocationPermission) + contentsDelegate->requestGeolocationPermission(request.origin); +} + +void PermissionManagerQt::CancelPermissionRequest(content::PermissionType permission, + content::WebContents* web_contents, + int request_id, + const GURL& requesting_origin) +{ + Q_UNUSED(web_contents); + const BrowserContextAdapter::PermissionType permissionType = toQt(permission); + if (permissionType == BrowserContextAdapter::UnsupportedPermission) + return; + + // Should we add API to cancel permissions in the UI level? + const QUrl origin = toQt(requesting_origin); + auto it = m_requests.begin(); + const auto end = m_requests.end(); + while (it != end) { + if (it->id == request_id && it->type == permissionType && it->origin == origin) { + m_requests.erase(it); + return; + } + } + qWarning() << "PermissionManagerQt::CancelPermissionRequest called on unknown request" << request_id << origin << permissionType; +} + +content::PermissionStatus PermissionManagerQt::GetPermissionStatus( + content::PermissionType permission, + const GURL& requesting_origin, + const GURL& /*embedding_origin*/) +{ + const BrowserContextAdapter::PermissionType permissionType = toQt(permission); + if (permissionType == BrowserContextAdapter::UnsupportedPermission) + return content::PERMISSION_STATUS_DENIED; + + QPair<QUrl, BrowserContextAdapter::PermissionType> key(toQt(requesting_origin), permissionType); + if (!m_permissions.contains(key)) + return content::PERMISSION_STATUS_ASK; + if (m_permissions[key]) + return content::PERMISSION_STATUS_GRANTED; + return content::PERMISSION_STATUS_DENIED; +} + +void PermissionManagerQt::ResetPermission( + content::PermissionType permission, + const GURL& requesting_origin, + const GURL& /*embedding_origin*/) +{ + const BrowserContextAdapter::PermissionType permissionType = toQt(permission); + if (permissionType == BrowserContextAdapter::UnsupportedPermission) + return; + + QPair<QUrl, BrowserContextAdapter::PermissionType> key(toQt(requesting_origin), permissionType); + m_permissions.remove(key); +} + +void PermissionManagerQt::RegisterPermissionUsage( + content::PermissionType /*permission*/, + const GURL& /*requesting_origin*/, + const GURL& /*embedding_origin*/) +{ + // We do not currently track which permissions are used. +} + +int PermissionManagerQt::SubscribePermissionStatusChange( + content::PermissionType permission, + const GURL& requesting_origin, + const GURL& /*embedding_origin*/, + const base::Callback<void(content::PermissionStatus)>& callback) +{ + Subscriber subscriber = { + m_subscriberCount++, + toQt(permission), + toQt(requesting_origin), + callback + }; + m_subscribers.append(subscriber); + return subscriber.id; +} + +void PermissionManagerQt::UnsubscribePermissionStatusChange(int subscription_id) +{ + for (int i = 0; i < m_subscribers.count(); i++) { + if (m_subscribers[i].id == subscription_id) { + m_subscribers.removeAt(i); + return; + } + } + qWarning() << "PermissionManagerQt::UnsubscribePermissionStatusChange called on unknown subscription id" << subscription_id; +} + +} // namespace QtWebEngineCore diff --git a/src/core/permission_manager_qt.h b/src/core/permission_manager_qt.h new file mode 100644 index 000000000..75f88f9a9 --- /dev/null +++ b/src/core/permission_manager_qt.h @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PERMISSION_MANAGER_QT_H +#define PERMISSION_MANAGER_QT_H + +#include "base/callback.h" +#include "content/public/browser/permission_manager.h" +#include "browser_context_adapter.h" + +#include <QHash> +#include <QList> + +namespace QtWebEngineCore { + +class PermissionManagerQt : public content::PermissionManager { + +public: + PermissionManagerQt(BrowserContextAdapter *); + ~PermissionManagerQt(); + typedef BrowserContextAdapter::PermissionType PermissionType; + + void permissionRequestReply(const QUrl &origin, PermissionType type, bool reply); + + // content::PermissionManager implementation: + void RequestPermission( + content::PermissionType permission, + content::WebContents* web_contents, + int request_id, + const GURL& requesting_origin, + bool user_gesture, + const base::Callback<void(content::PermissionStatus)>& callback) override; + + void CancelPermissionRequest( + content::PermissionType permission, + content::WebContents* web_contents, + int request_id, + const GURL& requesting_origin) override; + + content::PermissionStatus GetPermissionStatus( + content::PermissionType permission, + const GURL& requesting_origin, + const GURL& embedding_origin) override; + + void ResetPermission( + content::PermissionType permission, + const GURL& requesting_origin, + const GURL& embedding_origin) override; + + void RegisterPermissionUsage( + content::PermissionType permission, + const GURL& requesting_origin, + const GURL& embedding_origin) override; + + int SubscribePermissionStatusChange( + content::PermissionType permission, + const GURL& requesting_origin, + const GURL& embedding_origin, + const base::Callback<void(content::PermissionStatus)>& callback) override; + + void UnsubscribePermissionStatusChange(int subscription_id) override; + +private: + BrowserContextAdapter *m_contextAdapter; + QHash<QPair<QUrl, PermissionType>, bool> m_permissions; + struct Request { + int id; + PermissionType type; + QUrl origin; + base::Callback<void(content::PermissionStatus)> callback; + }; + QList<Request> m_requests; + struct Subscriber { + int id; + PermissionType type; + QUrl origin; + base::Callback<void(content::PermissionStatus)> callback; + }; + int m_subscriberCount; + QList<Subscriber> m_subscribers; + +}; + +} // namespace QtWebEngineCore + +#endif // PERMISSION_MANAGER_QT_H diff --git a/src/core/proxy_config_service_qt.cpp b/src/core/proxy_config_service_qt.cpp new file mode 100644 index 000000000..933b1a10e --- /dev/null +++ b/src/core/proxy_config_service_qt.cpp @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "proxy_config_service_qt.h" + +#include "proxy_resolver_qt.h" + +#include "base/bind.h" +#include "content/public/browser/browser_thread.h" + +using content::BrowserThread; + +net::ProxyServer ProxyConfigServiceQt::fromQNetworkProxy(const QNetworkProxy &qtProxy) +{ + net::ProxyServer::Scheme proxyScheme = net::ProxyServer::SCHEME_INVALID; + switch (qtProxy.type()) { + case QNetworkProxy::Socks5Proxy: + proxyScheme = net::ProxyServer::SCHEME_SOCKS5; + break; + case QNetworkProxy::HttpProxy: + case QNetworkProxy::HttpCachingProxy: + case QNetworkProxy::FtpCachingProxy: + proxyScheme = net::ProxyServer::SCHEME_HTTP; + break; + case QNetworkProxy::NoProxy: + default: + proxyScheme = net::ProxyServer::SCHEME_DIRECT; + break; + } + return net::ProxyServer(proxyScheme, net::HostPortPair(qtProxy.hostName().toStdString(), qtProxy.port())); +} + +//================ Based on ChromeProxyConfigService ======================= + +ProxyConfigServiceQt::ProxyConfigServiceQt(net::ProxyConfigService *baseService) + : m_baseService(baseService), + m_registeredObserver(false) +{ +} + +ProxyConfigServiceQt::~ProxyConfigServiceQt() +{ + if (m_registeredObserver && m_baseService.get()) + m_baseService->RemoveObserver(this); +} + +void ProxyConfigServiceQt::AddObserver(net::ProxyConfigService::Observer *observer) +{ + RegisterObserver(); + m_observers.AddObserver(observer); +} + +void ProxyConfigServiceQt::RemoveObserver(net::ProxyConfigService::Observer *observer) +{ + m_observers.RemoveObserver(observer); +} + +net::ProxyConfigService::ConfigAvailability ProxyConfigServiceQt::GetLatestProxyConfig(net::ProxyConfig *config) +{ + RegisterObserver(); + + // Ask the base service if available. + net::ProxyConfig systemConfig; + ConfigAvailability systemAvailability = net::ProxyConfigService::CONFIG_UNSET; + if (m_baseService.get()) + systemAvailability = m_baseService->GetLatestProxyConfig(&systemConfig); + + const QNetworkProxy &qtProxy = QNetworkProxy::applicationProxy(); + if (qtProxy == m_qtApplicationProxy && !m_qtProxyConfig.proxy_rules().empty()) { + *config = m_qtProxyConfig; + return CONFIG_VALID; + } + m_qtApplicationProxy = qtProxy; + m_qtProxyConfig = (systemAvailability == CONFIG_VALID) ? systemConfig : net::ProxyConfig(); + const bool useProxyResolver = ProxyResolverQt::useProxyResolverQt(); + + if (qtProxy.type() == QNetworkProxy::NoProxy) { + *config = systemConfig; + if (useProxyResolver) { + config->set_auto_detect(true); + config->set_pac_mandatory(true); + } + return systemAvailability; + } + + net::ProxyConfig::ProxyRules qtRules; + net::ProxyServer server = fromQNetworkProxy(qtProxy); + switch (qtProxy.type()) { + case QNetworkProxy::HttpProxy: + case QNetworkProxy::Socks5Proxy: + qtRules.type = net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY; + qtRules.single_proxies.SetSingleProxyServer(server); + break; + case QNetworkProxy::HttpCachingProxy: + qtRules.type = net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME; + qtRules.proxies_for_http.SetSingleProxyServer(server); + break; + case QNetworkProxy::FtpCachingProxy: + qtRules.type = net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME; + qtRules.proxies_for_ftp.SetSingleProxyServer(server); + break; + default: + qtRules.type = net::ProxyConfig::ProxyRules::TYPE_NO_RULES; + } + + m_qtProxyConfig.proxy_rules() = qtRules; + if (useProxyResolver) { + m_qtProxyConfig.set_pac_mandatory(true); + m_qtProxyConfig.set_auto_detect(true); + } + *config = m_qtProxyConfig; + return CONFIG_VALID; +} + +void ProxyConfigServiceQt::OnLazyPoll() +{ + if (m_qtApplicationProxy != QNetworkProxy::applicationProxy()) { + net::ProxyConfig unusedConfig; + OnProxyConfigChanged(unusedConfig, CONFIG_VALID); + } + if (m_baseService.get()) + m_baseService->OnLazyPoll(); +} + + +void ProxyConfigServiceQt::OnProxyConfigChanged(const net::ProxyConfig &config, ConfigAvailability availability) +{ + Q_UNUSED(config); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + if (m_qtApplicationProxy != QNetworkProxy::applicationProxy() + || m_qtApplicationProxy.type() == QNetworkProxy::NoProxy) { + net::ProxyConfig actual_config; + availability = GetLatestProxyConfig(&actual_config); + if (availability == CONFIG_PENDING) + return; + FOR_EACH_OBSERVER(net::ProxyConfigService::Observer, m_observers, + OnProxyConfigChanged(actual_config, availability)); + } +} + +void ProxyConfigServiceQt::RegisterObserver() +{ + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + if (!m_registeredObserver && m_baseService.get()) { + m_baseService->AddObserver(this); + m_registeredObserver = true; + } +} diff --git a/src/core/proxy_config_service_qt.h b/src/core/proxy_config_service_qt.h new file mode 100644 index 000000000..f2f06d3fa --- /dev/null +++ b/src/core/proxy_config_service_qt.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PROXY_CONFIG_SERVICE_QT_H +#define PROXY_CONFIG_SERVICE_QT_H + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/observer_list.h" + +#include "net/proxy/proxy_config.h" +#include "net/proxy/proxy_config_service.h" + +#include <QNetworkProxy> + +class ProxyConfigServiceQt + : public net::ProxyConfigService, + public net::ProxyConfigService::Observer { +public: + + static net::ProxyServer fromQNetworkProxy(const QNetworkProxy &); + + explicit ProxyConfigServiceQt(net::ProxyConfigService *baseService); + ~ProxyConfigServiceQt() override; + + // ProxyConfigService implementation: + void AddObserver(net::ProxyConfigService::Observer *observer) override; + void RemoveObserver(net::ProxyConfigService::Observer *observer) override; + ConfigAvailability GetLatestProxyConfig(net::ProxyConfig *config) override; + void OnLazyPoll() override; + +private: + // ProxyConfigService::Observer implementation: + void OnProxyConfigChanged(const net::ProxyConfig& config, + ConfigAvailability availability) override; + + // Makes sure that the observer registration with the base service is set up. + void RegisterObserver(); + + scoped_ptr<net::ProxyConfigService> m_baseService; + ObserverList<net::ProxyConfigService::Observer, true> m_observers; + + // Keep the last QNetworkProxy::applicationProxy state around. + QNetworkProxy m_qtApplicationProxy; + net::ProxyConfig m_qtProxyConfig; + + // Indicates whether the base service registration is done. + bool m_registeredObserver; + + DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceQt); +}; + +#endif // PROXY_CONFIG_SERVICE_QT_H diff --git a/src/core/proxy_resolver_qt.cpp b/src/core/proxy_resolver_qt.cpp new file mode 100644 index 000000000..9db76e910 --- /dev/null +++ b/src/core/proxy_resolver_qt.cpp @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "proxy_resolver_qt.h" + +#include "proxy_config_service_qt.h" +#include "type_conversion.h" + +#include "net/base/load_states.h" +#include "net/base/net_errors.h" +#include "net/proxy/proxy_info.h" + +#include <QNetworkProxyFactory> +#include <QNetworkProxyQuery> + +ProxyResolverQt::ProxyResolverQt() + : net::ProxyResolver(/*expects_pac_bytes = */ false) +{ +} + +int ProxyResolverQt::GetProxyForURL(const GURL &url, net::ProxyInfo *results, const net::CompletionCallback &, net::ProxyResolver::RequestHandle *, const net::BoundNetLog &) +{ + QList<QNetworkProxy> proxies = QNetworkProxyFactory::systemProxyForQuery(QNetworkProxyQuery(QtWebEngineCore::toQt(url))); + if (proxies.empty()) + return net::ERR_FAILED; + if (proxies.size() == 1) { + const QNetworkProxy &qtProxy = proxies.first(); + if (qtProxy.type() == QNetworkProxy::NoProxy) + results->UseDirect(); + else + results->UseProxyServer(ProxyConfigServiceQt::fromQNetworkProxy(qtProxy)); + return net::OK; + } + net::ProxyList proxyList; + Q_FOREACH (const QNetworkProxy &qtProxy, proxies) + proxyList.AddProxyServer(ProxyConfigServiceQt::fromQNetworkProxy(qtProxy)); + results->UseProxyList(proxyList); + return net::OK; +} + +void ProxyResolverQt::CancelRequest(net::ProxyResolver::RequestHandle) +{ + // This is a synchronous ProxyResolver; no possibility for async requests. + NOTREACHED(); +} + +net::LoadState ProxyResolverQt::GetLoadState(net::ProxyResolver::RequestHandle) const +{ + NOTREACHED(); + return net::LOAD_STATE_IDLE; +} + +void ProxyResolverQt::CancelSetPacScript() +{ + NOTREACHED(); +} + +int ProxyResolverQt::SetPacScript(const scoped_refptr<net::ProxyResolverScriptData> &, const net::CompletionCallback &) { + return net::OK; +} diff --git a/src/core/proxy_resolver_qt.h b/src/core/proxy_resolver_qt.h new file mode 100644 index 000000000..4d419fb6e --- /dev/null +++ b/src/core/proxy_resolver_qt.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PROXY_RESOLVER_QT_H +#define PROXY_RESOLVER_QT_H + +#include "net/proxy/proxy_resolver.h" +#include "net/proxy/proxy_resolver_factory.h" +#include <qglobal.h> + + +class ProxyResolverQt : public net::ProxyResolver { +public: + static bool useProxyResolverQt() { return qEnvironmentVariableIsSet("QTWEBENGINE_USE_QT_PROXYRESOLVER"); } + + ProxyResolverQt(); + + int GetProxyForURL(const GURL &url, net::ProxyInfo *results, const net::CompletionCallback & + , RequestHandle*, const net::BoundNetLog&) override; + + void CancelRequest(RequestHandle) override; + + net::LoadState GetLoadState(RequestHandle) const override; + + void CancelSetPacScript() override; + + int SetPacScript(const scoped_refptr<net::ProxyResolverScriptData>& /*script_data*/, const net::CompletionCallback& /*callback*/) override; +}; + +class ProxyResolverFactoryQt : public net::LegacyProxyResolverFactory { +public: + ProxyResolverFactoryQt(bool expects_pac_bytes) : net::LegacyProxyResolverFactory(expects_pac_bytes) + { + } + scoped_ptr<net::ProxyResolver> CreateProxyResolver() override + { + return scoped_ptr<net::ProxyResolver>(new ProxyResolverQt()); + } +}; + +#endif // PROXY_RESOLVER_QT_H diff --git a/src/core/qtwebengine.gypi b/src/core/qtwebengine.gypi index cca2bd73f..cad6882eb 100644 --- a/src/core/qtwebengine.gypi +++ b/src/core/qtwebengine.gypi @@ -8,6 +8,8 @@ 'dependencies': [ '<(chromium_src_dir)/base/base.gyp:base', '<(chromium_src_dir)/base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', + '<(chromium_src_dir)/components/components.gyp:devtools_discovery', + '<(chromium_src_dir)/components/components.gyp:devtools_http_handler', '<(chromium_src_dir)/components/components.gyp:error_page_renderer', '<(chromium_src_dir)/components/components.gyp:visitedlink_browser', '<(chromium_src_dir)/components/components.gyp:visitedlink_renderer', @@ -16,6 +18,7 @@ '<(chromium_src_dir)/content/content.gyp:content_browser', '<(chromium_src_dir)/content/content.gyp:content_common', '<(chromium_src_dir)/content/content.gyp:content_gpu', + '<(chromium_src_dir)/content/content.gyp:content_ppapi_plugin', '<(chromium_src_dir)/content/content.gyp:content_renderer', '<(chromium_src_dir)/content/content.gyp:content_utility', '<(chromium_src_dir)/content/app/resources/content_resources.gyp:content_resources', diff --git a/src/core/qtwebengine_extras.gypi b/src/core/qtwebengine_extras.gypi index e28d6436e..86a4c17bb 100644 --- a/src/core/qtwebengine_extras.gypi +++ b/src/core/qtwebengine_extras.gypi @@ -57,6 +57,7 @@ ['exclude', 'win/accessibility_ids_win\\.h$'], ['exclude', 'win/accessibility_misc_utils\\.(cc|h)$'], ['exclude', 'win/atl_module\\.h$'], + ['exclude', 'audio_classifier\\.(cc|h)$'], ], 'defines': [ 'TOOLKIT_QT', diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 572bc340c..ef6610ecb 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -36,10 +36,12 @@ #include "render_widget_host_view_qt.h" +#include "common/qt_messages.h" #include "browser_accessibility_manager_qt.h" #include "browser_accessibility_qt.h" #include "chromium_overrides.h" #include "delegated_frame_node.h" +#include "qtwebenginecoreglobal_p.h" #include "render_widget_host_view_qt_delegate.h" #include "type_conversion.h" #include "web_contents_adapter.h" @@ -60,10 +62,11 @@ #include "third_party/WebKit/public/platform/WebCursorInfo.h" #include "third_party/WebKit/public/web/WebCompositionUnderline.h" #include "ui/base/clipboard/scoped_clipboard_writer.h" +#include "ui/events/blink/blink_event_util.h" #include "ui/events/event.h" #include "ui/events/gesture_detection/gesture_provider_config_helper.h" #include "ui/events/gesture_detection/motion_event.h" -#include "ui/gfx/size_conversions.h" +#include "ui/gfx/geometry/size_conversions.h" #include <QEvent> #include <QFocusEvent> @@ -142,7 +145,7 @@ static inline int firstAvailableId(const QMap<int, int> &map) } static inline ui::GestureProvider::Config QtGestureProviderConfig() { - ui::GestureProvider::Config config = ui::DefaultGestureProviderConfig(); + ui::GestureProvider::Config config = ui::GetGestureProviderConfig(ui::GestureProviderConfigType::CURRENT_PLATFORM); // Causes an assert in CreateWebGestureEventFromGestureEventData and we don't need them in Qt. config.gesture_begin_end_types_enabled = false; config.gesture_detector_config.swipe_enabled = false; @@ -180,12 +183,14 @@ static inline int flagsFromModifiers(Qt::KeyboardModifiers modifiers) return modifierFlags; } +static uint32 s_eventId = 0; class MotionEventQt : public ui::MotionEvent { public: MotionEventQt(const QList<QTouchEvent::TouchPoint> &touchPoints, const base::TimeTicks &eventTime, Action action, const Qt::KeyboardModifiers modifiers, int index = -1) : touchPoints(touchPoints) , eventTime(eventTime) , action(action) + , eventId(++s_eventId) , flags(flagsFromModifiers(modifiers)) , index(index) { @@ -193,7 +198,7 @@ public: Q_ASSERT((action != ACTION_DOWN && action != ACTION_UP) || index == 0); } - virtual int GetId() const Q_DECL_OVERRIDE { return 0; } + virtual uint32 GetUniqueEventId() const Q_DECL_OVERRIDE { return eventId; } virtual Action GetAction() const Q_DECL_OVERRIDE { return action; } virtual int GetActionIndex() const Q_DECL_OVERRIDE { return index; } virtual size_t GetPointerCount() const Q_DECL_OVERRIDE { return touchPoints.size(); } @@ -232,6 +237,7 @@ private: QList<QTouchEvent::TouchPoint> touchPoints; base::TimeTicks eventTime; Action action; + const uint32 eventId; int flags; int index; }; @@ -408,6 +414,14 @@ gfx::Rect RenderWidgetHostViewQt::GetViewBounds() const return gfx::BoundingRect(p1, p2); } +void RenderWidgetHostViewQt::SetBackgroundColor(SkColor color) { + RenderWidgetHostViewBase::SetBackgroundColor(color); + // Set the background of the compositor if necessary + m_delegate->setClearColor(toQt(color)); + // Set the background of the blink::FrameView + m_host->Send(new QtRenderViewObserver_SetBackgroundColor(m_host->GetRoutingID(), color)); +} + // Return value indicates whether the mouse is locked successfully or not. bool RenderWidgetHostViewQt::LockMouse() { @@ -426,27 +440,11 @@ void RenderWidgetHostViewQt::UnlockMouse() m_host->LostMouseLock(); } -void RenderWidgetHostViewQt::WasShown() -{ - m_host->WasShown(ui::LatencyInfo()); -} - -void RenderWidgetHostViewQt::WasHidden() -{ - m_host->WasHidden(); -} - void RenderWidgetHostViewQt::MovePluginWindows(const std::vector<content::WebPluginGeometry>&) { // QT_NOT_YET_IMPLEMENTED } -void RenderWidgetHostViewQt::Blur() -{ - m_host->SetInputMethodActive(false); - m_host->Blur(); -} - void RenderWidgetHostViewQt::UpdateCursor(const content::WebCursor &webCursor) { content::WebCursor::CursorInfo cursorInfo; @@ -600,13 +598,13 @@ void RenderWidgetHostViewQt::SelectionBoundsChanged(const ViewHostMsg_SelectionB m_cursorRect = QRect(caretRect.x(), caretRect.y(), caretRect.width(), caretRect.height()); } -void RenderWidgetHostViewQt::CopyFromCompositingSurface(const gfx::Rect& src_subrect, const gfx::Size& dst_size, content::CopyFromCompositingSurfaceCallback& callback, const SkColorType color_type) +void RenderWidgetHostViewQt::CopyFromCompositingSurface(const gfx::Rect& src_subrect, const gfx::Size& dst_size, content::ReadbackRequestCallback& callback, const SkColorType color_type) { NOTIMPLEMENTED(); Q_UNUSED(src_subrect); Q_UNUSED(dst_size); Q_UNUSED(color_type); - callback.Run(false, SkBitmap()); + callback.Run(SkBitmap(), content::READBACK_FAILED); } void RenderWidgetHostViewQt::CopyFromCompositingSurfaceToVideoFrame(const gfx::Rect& src_subrect, const scoped_refptr<media::VideoFrame>& target, const base::Callback<void(bool)>& callback) @@ -688,7 +686,7 @@ void RenderWidgetHostViewQt::SelectionChanged(const base::string16 &text, size_t void RenderWidgetHostViewQt::OnGestureEvent(const ui::GestureEventData& gesture) { - m_host->ForwardGestureEvent(content::CreateWebGestureEventFromGestureEventData(gesture)); + m_host->ForwardGestureEvent(ui::CreateWebGestureEventFromGestureEventData(gesture)); } QSGNode *RenderWidgetHostViewQt::updatePaintNode(QSGNode *oldNode) @@ -717,12 +715,12 @@ void RenderWidgetHostViewQt::notifyResize() void RenderWidgetHostViewQt::notifyShown() { - WasShown(); + m_host->WasShown(ui::LatencyInfo()); } void RenderWidgetHostViewQt::notifyHidden() { - WasHidden(); + m_host->WasHidden(); } void RenderWidgetHostViewQt::windowBoundsChanged() @@ -808,7 +806,7 @@ QVariant RenderWidgetHostViewQt::inputMethodQuery(Qt::InputMethodQuery query) co void RenderWidgetHostViewQt::ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch, content::InputEventAckState ack_result) { Q_UNUSED(touch); const bool eventConsumed = ack_result == content::INPUT_EVENT_ACK_STATE_CONSUMED; - m_gestureProvider.OnTouchEventAck(eventConsumed); + m_gestureProvider.OnAsyncTouchEventAck(eventConsumed); } void RenderWidgetHostViewQt::sendDelegatedFrameAck() @@ -822,16 +820,10 @@ void RenderWidgetHostViewQt::sendDelegatedFrameAck() void RenderWidgetHostViewQt::processMotionEvent(const ui::MotionEvent &motionEvent) { - if (!m_gestureProvider.OnTouchEvent(motionEvent)) + if (!m_gestureProvider.OnTouchEvent(motionEvent).succeeded) return; - // Short-circuit touch forwarding if no touch handlers exist. - if (!m_host->ShouldForwardTouchEvent()) { - const bool eventConsumed = false; - m_gestureProvider.OnTouchEventAck(eventConsumed); - return; - } - blink::WebTouchEvent touchEvent = content::CreateWebTouchEventFromMotionEvent(motionEvent); + blink::WebTouchEvent touchEvent = ui::CreateWebTouchEventFromMotionEvent(motionEvent, false); m_host->ForwardTouchEventWithLatencyInfo(touchEvent, CreateLatencyInfo(touchEvent)); } diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h index 248c52f6e..274138dcf 100644 --- a/src/core/render_widget_host_view_qt.h +++ b/src/core/render_widget_host_view_qt.h @@ -47,6 +47,7 @@ #include "content/common/gpu/gpu_messages.h" #include "content/common/view_messages.h" #include "ui/events/gesture_detection/filtered_gesture_provider.h" +#include "qtwebenginecoreglobal_p.h" #include <QMap> #include <QPoint> #include <QRect> @@ -125,12 +126,10 @@ public: virtual void Hide() Q_DECL_OVERRIDE; virtual bool IsShowing() Q_DECL_OVERRIDE; virtual gfx::Rect GetViewBounds() const Q_DECL_OVERRIDE; + virtual void SetBackgroundColor(SkColor color) Q_DECL_OVERRIDE; virtual bool LockMouse() Q_DECL_OVERRIDE; virtual void UnlockMouse() Q_DECL_OVERRIDE; - virtual void WasShown() Q_DECL_OVERRIDE; - virtual void WasHidden() Q_DECL_OVERRIDE; virtual void MovePluginWindows(const std::vector<content::WebPluginGeometry>&) Q_DECL_OVERRIDE; - virtual void Blur() Q_DECL_OVERRIDE; virtual void UpdateCursor(const content::WebCursor&) Q_DECL_OVERRIDE; virtual void SetIsLoading(bool) Q_DECL_OVERRIDE; virtual void TextInputTypeChanged(ui::TextInputType type, ui::TextInputMode mode, bool can_compose_inline, int flags) Q_DECL_OVERRIDE; @@ -140,7 +139,7 @@ public: virtual void Destroy() Q_DECL_OVERRIDE; virtual void SetTooltipText(const base::string16 &tooltip_text) Q_DECL_OVERRIDE; virtual void SelectionBoundsChanged(const ViewHostMsg_SelectionBounds_Params&) Q_DECL_OVERRIDE; - virtual void CopyFromCompositingSurface(const gfx::Rect& src_subrect, const gfx::Size& dst_size, content::CopyFromCompositingSurfaceCallback& callback, const SkColorType color_type) Q_DECL_OVERRIDE; + virtual void CopyFromCompositingSurface(const gfx::Rect& src_subrect, const gfx::Size& dst_size, content::ReadbackRequestCallback& callback, const SkColorType color_type) Q_DECL_OVERRIDE; virtual void CopyFromCompositingSurfaceToVideoFrame(const gfx::Rect& src_subrect, const scoped_refptr<media::VideoFrame>& target, const base::Callback<void(bool)>& callback) Q_DECL_OVERRIDE; virtual bool CanCopyToVideoFrame() const Q_DECL_OVERRIDE; virtual bool HasAcceleratedSurface(const gfx::Size&) Q_DECL_OVERRIDE; diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h index da595b91f..f4aa9b27d 100644 --- a/src/core/render_widget_host_view_qt_delegate.h +++ b/src/core/render_widget_host_view_qt_delegate.h @@ -96,6 +96,7 @@ public: virtual void move(const QPoint &) = 0; virtual void inputMethodStateChanged(bool editorVisible) = 0; virtual void setTooltip(const QString &) = 0; + virtual void setClearColor(const QColor &color) = 0; }; } // namespace QtWebEngineCore diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp index e1333144a..32ba4d55f 100644 --- a/src/core/renderer/content_renderer_client_qt.cpp +++ b/src/core/renderer/content_renderer_client_qt.cpp @@ -51,6 +51,7 @@ #include "content/public/common/web_preferences.h" #include "renderer/web_channel_ipc_transport.h" +#include "renderer/qt_render_frame_observer.h" #include "renderer/qt_render_view_observer.h" #include "renderer/user_script_controller.h" @@ -85,6 +86,11 @@ void ContentRendererClientQt::RenderViewCreated(content::RenderView* render_view UserScriptController::instance()->renderViewCreated(render_view); } +void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame* render_frame) +{ + new QtWebEngineCore::QtRenderFrameObserver(render_frame); +} + bool ContentRendererClientQt::HasErrorPage(int httpStatusCode, std::string *errorDomain) { // Use an internal error page, if we have one for the status code. diff --git a/src/core/renderer/content_renderer_client_qt.h b/src/core/renderer/content_renderer_client_qt.h index dcb4e7fcb..fab88441f 100644 --- a/src/core/renderer/content_renderer_client_qt.h +++ b/src/core/renderer/content_renderer_client_qt.h @@ -53,7 +53,7 @@ public: ~ContentRendererClientQt(); virtual void RenderThreadStarted() Q_DECL_OVERRIDE; virtual void RenderViewCreated(content::RenderView *render_view) Q_DECL_OVERRIDE; - + virtual void RenderFrameCreated(content::RenderFrame* render_frame) Q_DECL_OVERRIDE; virtual bool ShouldSuppressErrorPage(content::RenderFrame *, const GURL &) Q_DECL_OVERRIDE; virtual bool HasErrorPage(int httpStatusCode, std::string *errorDomain) Q_DECL_OVERRIDE; virtual void GetNavigationErrorStrings(content::RenderView* renderView, blink::WebFrame* frame, const blink::WebURLRequest& failedRequest diff --git a/src/core/renderer/pepper/pepper_flash_browser_host_qt.cpp b/src/core/renderer/pepper/pepper_flash_browser_host_qt.cpp new file mode 100644 index 000000000..625e89ae4 --- /dev/null +++ b/src/core/renderer/pepper/pepper_flash_browser_host_qt.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "pepper_flash_browser_host_qt.h" + +#include "base/time/time.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_ppapi_host.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_process_host.h" +#include "ipc/ipc_message_macros.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/private/ppb_flash.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/resource_message_params.h" +#include "ppapi/shared_impl/time_conversion.h" +#include "qtwebenginecoreglobal_p.h" +#include "url/gurl.h" + +#if defined(OS_WIN) +#include <windows.h> +#elif defined(OS_MACOSX) +#include <CoreServices/CoreServices.h> +#endif + +using content::BrowserPpapiHost; +using content::BrowserThread; +using content::RenderProcessHost; + +namespace QtWebEngineCore { + + +PepperFlashBrowserHostQt::PepperFlashBrowserHostQt(BrowserPpapiHost* host, + PP_Instance instance, + PP_Resource resource) + : ResourceHost(host->GetPpapiHost(), instance, resource), + host_(host), + weak_factory_(this) +{ + int unused; + host->GetRenderFrameIDsForInstance(instance, &render_process_id_, &unused); +} + +PepperFlashBrowserHostQt::~PepperFlashBrowserHostQt() {} + +int32_t PepperFlashBrowserHostQt::OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) +{ + PPAPI_BEGIN_MESSAGE_MAP(PepperFlashBrowserHostQt, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Flash_UpdateActivity, + OnUpdateActivity) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_GetLocalTimeZoneOffset, + OnGetLocalTimeZoneOffset) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Flash_GetLocalDataRestrictions, + OnGetLocalDataRestrictions) + PPAPI_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t PepperFlashBrowserHostQt::OnUpdateActivity(ppapi::host::HostMessageContext* host_context) +{ +#if defined(OS_WIN) + // Reading then writing back the same value to the screensaver timeout system + // setting resets the countdown which prevents the screensaver from turning + // on "for a while". As long as the plugin pings us with this message faster + // than the screensaver timeout, it won't go on. + int value = 0; + if (SystemParametersInfo(SPI_GETSCREENSAVETIMEOUT, 0, &value, 0)) + SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, value, NULL, 0); +#elif defined(OS_MACOSX) + UpdateSystemActivity(OverallAct); +#endif + return PP_OK; +} + +int32_t PepperFlashBrowserHostQt::OnGetLocalTimeZoneOffset( + ppapi::host::HostMessageContext* host_context, + const base::Time& t) +{ + // The reason for this processing being in the browser process is that on + // Linux, the localtime calls require filesystem access prohibited by the + // sandbox. + host_context->reply_msg = PpapiPluginMsg_Flash_GetLocalTimeZoneOffsetReply( + ppapi::PPGetLocalTimeZoneOffset(t)); + return PP_OK; +} + +int32_t PepperFlashBrowserHostQt::OnGetLocalDataRestrictions( + ppapi::host::HostMessageContext* context) +{ + QT_NOT_YET_IMPLEMENTED + return PP_OK; +} + +} // namespace QtWebEngineCore diff --git a/src/core/renderer/pepper/pepper_flash_browser_host_qt.h b/src/core/renderer/pepper/pepper_flash_browser_host_qt.h new file mode 100644 index 000000000..c5165a1b0 --- /dev/null +++ b/src/core/renderer/pepper/pepper_flash_browser_host_qt.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PEPPER_FLASH_BROWSER_HOST_QT_H +#define PEPPER_FLASH_BROWSER_HOST_QT_H + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/resource_host.h" + +namespace base { +class Time; +} + +namespace content { +class BrowserPpapiHost; +class ResourceContext; +} + +class GURL; + +namespace QtWebEngineCore { + +class PepperFlashBrowserHostQt : public ppapi::host::ResourceHost { +public: + PepperFlashBrowserHostQt(content::BrowserPpapiHost* host, + PP_Instance instance, + PP_Resource resource); + ~PepperFlashBrowserHostQt() override; + + // ppapi::host::ResourceHost override. + int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) override; + +private: + int32_t OnUpdateActivity(ppapi::host::HostMessageContext* host_context); + int32_t OnGetLocalTimeZoneOffset( + ppapi::host::HostMessageContext* host_context, + const base::Time& t); + int32_t OnGetLocalDataRestrictions(ppapi::host::HostMessageContext* context); + + void GetLocalDataRestrictions(ppapi::host::ReplyMessageContext reply_context, + const GURL& document_url, + const GURL& plugin_url); + + content::BrowserPpapiHost* host_; + int render_process_id_; + base::WeakPtrFactory<PepperFlashBrowserHostQt> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(PepperFlashBrowserHostQt); +}; + +} // namespace QtWebEngineCore + +#endif // PEPPER_FLASH_BROWSER_HOST_QT_H diff --git a/src/core/renderer/pepper/pepper_flash_renderer_host_qt.cpp b/src/core/renderer/pepper/pepper_flash_renderer_host_qt.cpp new file mode 100644 index 000000000..8e68d1682 --- /dev/null +++ b/src/core/renderer/pepper/pepper_flash_renderer_host_qt.cpp @@ -0,0 +1,349 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "pepper_flash_renderer_host_qt.h" + +#include <map> +#include <vector> + +#include "base/lazy_instance.h" +#include "base/metrics/histogram.h" +#include "base/strings/string_util.h" +#include "content/public/renderer/pepper_plugin_instance.h" +#include "content/public/renderer/render_thread.h" +#include "content/public/renderer/renderer_ppapi_host.h" +#include "ipc/ipc_message_macros.h" +#include "net/http/http_util.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/trusted/ppb_browser_font_trusted.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/proxy/host_dispatcher.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/resource_message_params.h" +#include "ppapi/proxy/serialized_structs.h" +#include "ppapi/thunk/enter.h" +#include "ppapi/thunk/ppb_image_data_api.h" +#include "skia/ext/platform_canvas.h" +#include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkMatrix.h" +#include "third_party/skia/include/core/SkPaint.h" +#include "third_party/skia/include/core/SkPoint.h" +#include "third_party/skia/include/core/SkTemplates.h" +#include "third_party/skia/include/core/SkTypeface.h" +#include "ui/gfx/geometry/rect.h" +#include "url/gurl.h" + +using ppapi::thunk::EnterResourceNoLock; +using ppapi::thunk::PPB_ImageData_API; + +namespace { + +// Some non-simple HTTP request headers that Flash may set. +// (Please see http://www.w3.org/TR/cors/#simple-header for the definition of +// simple headers.) +// +// The list and the enum defined below are used to collect data about request +// headers used in PPB_Flash.Navigate() calls, in order to understand the impact +// of rejecting PPB_Flash.Navigate() requests with non-simple headers. +// +// TODO(yzshen): We should be able to remove the histogram recording code once +// we get the answer. +const char* const kRejectedHttpRequestHeaders[] = { + "authorization", // + "cache-control", // + "content-encoding", // + "content-md5", // + "content-type", // If the media type is not one of those covered by the + // simple header definition. + "expires", // + "from", // + "if-match", // + "if-none-match", // + "if-range", // + "if-unmodified-since", // + "pragma", // + "referer" // +}; + +// Please note that new entries should be added right above +// FLASH_NAVIGATE_USAGE_ENUM_COUNT, and existing entries shouldn't be re-ordered +// or removed, since this ordering is used in a histogram. +enum FlashNavigateUsage { + // This section must be in the same order as kRejectedHttpRequestHeaders. + REJECT_AUTHORIZATION = 0, + REJECT_CACHE_CONTROL, + REJECT_CONTENT_ENCODING, + REJECT_CONTENT_MD5, + REJECT_CONTENT_TYPE, + REJECT_EXPIRES, + REJECT_FROM, + REJECT_IF_MATCH, + REJECT_IF_NONE_MATCH, + REJECT_IF_RANGE, + REJECT_IF_UNMODIFIED_SINCE, + REJECT_PRAGMA, + REJECT_REFERER, + + // The navigate request is rejected because of headers not listed above + // (e.g., custom headers). + REJECT_OTHER_HEADERS, + + // Total number of rejected navigate requests. + TOTAL_REJECTED_NAVIGATE_REQUESTS, + + // Total number of navigate requests. + TOTAL_NAVIGATE_REQUESTS, + FLASH_NAVIGATE_USAGE_ENUM_COUNT +}; + +static base::LazyInstance<std::map<std::string, FlashNavigateUsage> > +g_rejected_headers = LAZY_INSTANCE_INITIALIZER; + +bool IsSimpleHeader(const std::string& lower_case_header_name, + const std::string& header_value) +{ + if (lower_case_header_name == "accept" || + lower_case_header_name == "accept-language" || + lower_case_header_name == "content-language") + return true; + + if (lower_case_header_name == "content-type") { + std::string lower_case_mime_type; + std::string lower_case_charset; + bool had_charset = false; + net::HttpUtil::ParseContentType(header_value, + &lower_case_mime_type, + &lower_case_charset, + &had_charset, + NULL); + return lower_case_mime_type == "application/x-www-form-urlencoded" || + lower_case_mime_type == "multipart/form-data" || + lower_case_mime_type == "text/plain"; + } + + return false; +} + +void RecordFlashNavigateUsage(FlashNavigateUsage usage) +{ + DCHECK_NE(FLASH_NAVIGATE_USAGE_ENUM_COUNT, usage); + UMA_HISTOGRAM_ENUMERATION( + "Plugin.FlashNavigateUsage", + usage, + FLASH_NAVIGATE_USAGE_ENUM_COUNT); +} + +} // namespace + +namespace QtWebEngineCore { + +PepperFlashRendererHostQt::PepperFlashRendererHostQt( + content::RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource) + : ResourceHost(host->GetPpapiHost(), instance, resource), + host_(host), + weak_factory_(this) +{ +} + +PepperFlashRendererHostQt::~PepperFlashRendererHostQt() { + // This object may be destroyed in the middle of a sync message. If that is + // the case, make sure we respond to all the pending navigate calls. + std::vector<ppapi::host::ReplyMessageContext>::reverse_iterator it; + for (it = navigate_replies_.rbegin(); it != navigate_replies_.rend(); ++it) + SendReply(*it, IPC::Message()); +} + +int32_t PepperFlashRendererHostQt::OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) +{ + PPAPI_BEGIN_MESSAGE_MAP(PepperFlashRendererHostQt, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_GetProxyForURL, + OnGetProxyForURL) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_SetInstanceAlwaysOnTop, + OnSetInstanceAlwaysOnTop) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_DrawGlyphs, + OnDrawGlyphs) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_Navigate, OnNavigate) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_Flash_IsRectTopmost, + OnIsRectTopmost) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_Flash_InvokePrinting, + OnInvokePrinting) + PPAPI_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t PepperFlashRendererHostQt::OnGetProxyForURL( + ppapi::host::HostMessageContext* host_context, + const std::string& url) +{ + GURL gurl(url); + if (!gurl.is_valid()) + return PP_ERROR_FAILED; + std::string proxy; + bool result = content::RenderThread::Get()->ResolveProxy(gurl, &proxy); + if (!result) + return PP_ERROR_FAILED; + host_context->reply_msg = PpapiPluginMsg_Flash_GetProxyForURLReply(proxy); + return PP_OK; +} + +int32_t PepperFlashRendererHostQt::OnSetInstanceAlwaysOnTop( + ppapi::host::HostMessageContext* host_context, + bool on_top) +{ + content::PepperPluginInstance* plugin_instance = + host_->GetPluginInstance(pp_instance()); + if (plugin_instance) + plugin_instance->SetAlwaysOnTop(on_top); + return PP_OK; +} + +int32_t PepperFlashRendererHostQt::OnDrawGlyphs( + ppapi::host::HostMessageContext* host_context, + ppapi::proxy::PPBFlash_DrawGlyphs_Params params) +{ + if (params.glyph_indices.size() != params.glyph_advances.size() || + params.glyph_indices.empty()) + return PP_ERROR_FAILED; + + return PP_OK; +} + +// CAUTION: This code is subtle because Navigate is a sync call which may +// cause re-entrancy or cause the instance to be destroyed. If the instance +// is destroyed we need to ensure that we respond to all outstanding sync +// messages so that the plugin process does not remain blocked. +int32_t PepperFlashRendererHostQt::OnNavigate( + ppapi::host::HostMessageContext* host_context, + const ppapi::URLRequestInfoData& data, + const std::string& target, + bool from_user_action) +{ + // If our PepperPluginInstance is already destroyed, just return a failure. + content::PepperPluginInstance* plugin_instance = + host_->GetPluginInstance(pp_instance()); + if (!plugin_instance) + return PP_ERROR_FAILED; + + std::map<std::string, FlashNavigateUsage>& rejected_headers = + g_rejected_headers.Get(); + if (rejected_headers.empty()) { + for (size_t i = 0; i < arraysize(kRejectedHttpRequestHeaders); ++i) + rejected_headers[kRejectedHttpRequestHeaders[i]] = + static_cast<FlashNavigateUsage>(i); + } + + net::HttpUtil::HeadersIterator header_iter( + data.headers.begin(), data.headers.end(), "\n\r"); + bool rejected = false; + while (header_iter.GetNext()) { + std::string lower_case_header_name = + base::StringToLowerASCII(header_iter.name()); + if (!IsSimpleHeader(lower_case_header_name, header_iter.values())) { + rejected = true; + + std::map<std::string, FlashNavigateUsage>::const_iterator iter = + rejected_headers.find(lower_case_header_name); + FlashNavigateUsage usage = + iter != rejected_headers.end() ? iter->second : REJECT_OTHER_HEADERS; + RecordFlashNavigateUsage(usage); + } + } + + RecordFlashNavigateUsage(TOTAL_NAVIGATE_REQUESTS); + if (rejected) { + RecordFlashNavigateUsage(TOTAL_REJECTED_NAVIGATE_REQUESTS); + return PP_ERROR_NOACCESS; + } + + // Navigate may call into Javascript (e.g. with a "javascript:" URL), + // or do things like navigate away from the page, either one of which will + // need to re-enter into the plugin. It is safe, because it is essentially + // equivalent to NPN_GetURL, where Flash would expect re-entrancy. + ppapi::proxy::HostDispatcher* host_dispatcher = + ppapi::proxy::HostDispatcher::GetForInstance(pp_instance()); + host_dispatcher->set_allow_plugin_reentrancy(); + + // Grab a weak pointer to ourselves on the stack so we can check if we are + // still alive. + base::WeakPtr<PepperFlashRendererHostQt> weak_ptr = weak_factory_.GetWeakPtr(); + // Keep track of reply contexts in case we are destroyed during a Navigate + // call. Even if we are destroyed, we still need to send these replies to + // unblock the plugin process. + navigate_replies_.push_back(host_context->MakeReplyMessageContext()); + plugin_instance->Navigate(data, target.c_str(), from_user_action); + // This object might have been destroyed by this point. If it is destroyed + // the reply will be sent in the destructor. Otherwise send the reply here. + if (weak_ptr.get()) { + SendReply(navigate_replies_.back(), IPC::Message()); + navigate_replies_.pop_back(); + } + + // Return PP_OK_COMPLETIONPENDING so that no reply is automatically sent. + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperFlashRendererHostQt::OnIsRectTopmost( + ppapi::host::HostMessageContext* host_context, + const PP_Rect& rect) +{ + content::PepperPluginInstance* plugin_instance = + host_->GetPluginInstance(pp_instance()); + if (plugin_instance && + plugin_instance->IsRectTopmost( + gfx::Rect( + rect.point.x, + rect.point.y, + rect.size.width, + rect.size.height))) + return PP_OK; + return PP_ERROR_FAILED; +} + +int32_t PepperFlashRendererHostQt::OnInvokePrinting( + ppapi::host::HostMessageContext* host_context) +{ + return PP_ERROR_FAILED; +} + +} //QtWebEngineCore diff --git a/src/core/renderer/pepper/pepper_flash_renderer_host_qt.h b/src/core/renderer/pepper/pepper_flash_renderer_host_qt.h new file mode 100644 index 000000000..4a731fad4 --- /dev/null +++ b/src/core/renderer/pepper/pepper_flash_renderer_host_qt.h @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PEPPER_FLASH_RENDERER_HOST_QT_H +#define PEPPER_FLASH_RENDERER_HOST_QT_H + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/memory/weak_ptr.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/resource_host.h" + +struct PP_Rect; + +namespace ppapi { +struct URLRequestInfoData; +} + +namespace ppapi { +namespace proxy { +struct PPBFlash_DrawGlyphs_Params; +} +} + +namespace content { +class RendererPpapiHost; +} + +namespace QtWebEngineCore { + +class PepperFlashRendererHostQt : public ppapi::host::ResourceHost { +public: + PepperFlashRendererHostQt(content::RendererPpapiHost* host, + PP_Instance instance, + PP_Resource resource); + ~PepperFlashRendererHostQt() override; + + // ppapi::host::ResourceHost override. + int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) override; + +private: + int32_t OnGetProxyForURL(ppapi::host::HostMessageContext* host_context, + const std::string& url); + int32_t OnSetInstanceAlwaysOnTop( + ppapi::host::HostMessageContext* host_context, + bool on_top); + int32_t OnDrawGlyphs(ppapi::host::HostMessageContext* host_context, + ppapi::proxy::PPBFlash_DrawGlyphs_Params params); + int32_t OnNavigate(ppapi::host::HostMessageContext* host_context, + const ppapi::URLRequestInfoData& data, + const std::string& target, + bool from_user_action); + int32_t OnIsRectTopmost(ppapi::host::HostMessageContext* host_context, + const PP_Rect& rect); + int32_t OnInvokePrinting(ppapi::host::HostMessageContext* host_context); + + // A stack of ReplyMessageContexts to track Navigate() calls which have not + // yet been replied to. + std::vector<ppapi::host::ReplyMessageContext> navigate_replies_; + + content::RendererPpapiHost* host_; + base::WeakPtrFactory<PepperFlashRendererHostQt> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(PepperFlashRendererHostQt); +}; + +} //QtWebEngineCore +#endif // PEPPER_FLASH_RENDERER_HOST_QT_H diff --git a/src/core/renderer/pepper/pepper_host_factory_qt.cpp b/src/core/renderer/pepper/pepper_host_factory_qt.cpp new file mode 100644 index 000000000..61eeac9a0 --- /dev/null +++ b/src/core/renderer/pepper/pepper_host_factory_qt.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "pepper_host_factory_qt.h" + +#include "build/build_config.h" +#include "content/public/browser/browser_ppapi_host.h" +#include "ppapi/host/message_filter_host.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/host/resource_host.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/ppapi_permissions.h" +#include "pepper_flash_browser_host_qt.h" + +using ppapi::host::MessageFilterHost; +using ppapi::host::ResourceHost; +using ppapi::host::ResourceMessageFilter; + +namespace QtWebEngineCore { + +PepperHostFactoryQt::PepperHostFactoryQt(content::BrowserPpapiHost* host) + : host_(host) +{ +} + +PepperHostFactoryQt::~PepperHostFactoryQt() {} + +scoped_ptr<ppapi::host::ResourceHost> PepperHostFactoryQt::CreateResourceHost(ppapi::host::PpapiHost* host, + PP_Resource resource, + PP_Instance instance, + const IPC::Message& message) +{ + DCHECK(host == host_->GetPpapiHost()); + + + if (!host_->IsValidInstance(instance)) + return scoped_ptr<ppapi::host::ResourceHost>(); + + if (host_->GetPpapiHost()->permissions().HasPermission(ppapi::PERMISSION_FLASH) + && message.type() == PpapiHostMsg_Flash_Create::ID) + return scoped_ptr<ppapi::host::ResourceHost>( + new PepperFlashBrowserHostQt(host_, + instance, + resource)); + + return scoped_ptr<ppapi::host::ResourceHost>(); +} + +} // namespace QtWebEngineCore diff --git a/src/core/renderer/pepper/pepper_host_factory_qt.h b/src/core/renderer/pepper/pepper_host_factory_qt.h new file mode 100644 index 000000000..22bf87b1b --- /dev/null +++ b/src/core/renderer/pepper/pepper_host_factory_qt.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PEPPER_HOST_FACTORY_QT_H +#define PEPPER_HOST_FACTORY_QT_H + +#include "base/compiler_specific.h" +#include "ppapi/host/host_factory.h" +#include "ppapi/host/resource_host.h" +#include "ppapi/host/ppapi_host.h" + +namespace content { +class BrowserPpapiHost; +} // namespace content + +namespace QtWebEngineCore { + +class PepperHostFactoryQt final : public ppapi::host::HostFactory { +public: + // Non-owning pointer to the filter must outlive this class. + explicit PepperHostFactoryQt(content::BrowserPpapiHost* host); + ~PepperHostFactoryQt() override; + + virtual scoped_ptr<ppapi::host::ResourceHost> CreateResourceHost( + ppapi::host::PpapiHost* host, + PP_Resource resource, + PP_Instance instance, + const IPC::Message& message) override; +private: + // Non-owning pointer. + content::BrowserPpapiHost* host_; + + DISALLOW_COPY_AND_ASSIGN(PepperHostFactoryQt); +}; +} // namespace QtWebEngineCore + +#endif // PEPPER_HOST_FACTORY_QT_H diff --git a/src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp b/src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp new file mode 100644 index 000000000..51416d698 --- /dev/null +++ b/src/core/renderer/pepper/pepper_renderer_host_factory_qt.cpp @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "pepper_renderer_host_factory_qt.h" +#include "pepper_flash_renderer_host_qt.h" +#include "content/public/renderer/renderer_ppapi_host.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/host/resource_host.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/ppapi_message_utils.h" +#include "ppapi/shared_impl/ppapi_permissions.h" + + +namespace QtWebEngineCore { + +PepperRendererHostFactoryQt::PepperRendererHostFactoryQt(content::RendererPpapiHost* host) + : host_(host) +{ +} + +PepperRendererHostFactoryQt::~PepperRendererHostFactoryQt() +{ +} + +scoped_ptr<ppapi::host::ResourceHost> PepperRendererHostFactoryQt::CreateResourceHost( + ppapi::host::PpapiHost* host, + PP_Resource resource, + PP_Instance instance, + const IPC::Message& message) +{ + DCHECK_EQ(host_->GetPpapiHost(), host); + + if (!host_->IsValidInstance(instance)) + return scoped_ptr<ppapi::host::ResourceHost>(); + + if (host_->GetPpapiHost()->permissions().HasPermission(ppapi::PERMISSION_FLASH) + && message.type() == PpapiHostMsg_Flash_Create::ID) + return scoped_ptr<ppapi::host::ResourceHost>( + new PepperFlashRendererHostQt(host_, + instance, + resource)); + + return scoped_ptr<ppapi::host::ResourceHost>(); +} + +} // QtWebEngineCore diff --git a/src/core/renderer/pepper/pepper_renderer_host_factory_qt.h b/src/core/renderer/pepper/pepper_renderer_host_factory_qt.h new file mode 100644 index 000000000..8631c1e03 --- /dev/null +++ b/src/core/renderer/pepper/pepper_renderer_host_factory_qt.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PEPPER_RENDERER_HOST_FACTORY_QT_H +#define PEPPER_RENDERER_HOST_FACTORY_QT_H + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "ppapi/host/host_factory.h" +#include "content/public/renderer/render_frame_observer.h" + + +namespace content { +class RenderFrame; +} + +namespace QtWebEngineCore { + +class PepperRendererHostFactoryQt : public ppapi::host::HostFactory { +public: + explicit PepperRendererHostFactoryQt(content::RendererPpapiHost* host); + ~PepperRendererHostFactoryQt(); + + // HostFactory. + scoped_ptr<ppapi::host::ResourceHost> CreateResourceHost( + ppapi::host::PpapiHost* host, + PP_Resource resource, + PP_Instance instance, + const IPC::Message& message) override; + +private: + // Not owned by this object. + content::RendererPpapiHost* host_; + + DISALLOW_COPY_AND_ASSIGN(PepperRendererHostFactoryQt); +}; + +} // namespace QtWebEngineCore + +#endif // PEPPER_RENDERER_HOST_FACTORY_QT_H diff --git a/src/core/renderer/qt_render_frame_observer.cpp b/src/core/renderer/qt_render_frame_observer.cpp new file mode 100644 index 000000000..5f06d1e4e --- /dev/null +++ b/src/core/renderer/qt_render_frame_observer.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qt_render_frame_observer.h" + +#include "content/public/renderer/renderer_ppapi_host.h" +#include "ppapi/host/ppapi_host.h" + +#include "renderer/pepper/pepper_renderer_host_factory_qt.h" +#include "renderer/pepper/pepper_flash_renderer_host_qt.h" + +namespace QtWebEngineCore { + +QtRenderFrameObserver::QtRenderFrameObserver(content::RenderFrame* render_frame) + : RenderFrameObserver(render_frame) +{ +} + +QtRenderFrameObserver::~QtRenderFrameObserver() +{ +} + +#if defined(ENABLE_PLUGINS) +void QtRenderFrameObserver::DidCreatePepperPlugin(content::RendererPpapiHost* host) +{ + host->GetPpapiHost()->AddHostFactoryFilter( + scoped_ptr<ppapi::host::HostFactory>( + new PepperRendererHostFactoryQt(host))); +} +#endif + +} // namespace QtWebEngineCore diff --git a/src/core/renderer/qt_render_frame_observer.h b/src/core/renderer/qt_render_frame_observer.h new file mode 100644 index 000000000..42f2b7464 --- /dev/null +++ b/src/core/renderer/qt_render_frame_observer.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QT_RENDER_FRAME_OBSERVER_H +#define QT_RENDER_FRAME_OBSERVER_H + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "content/public/renderer/render_frame_observer.h" + + +namespace content { +class RenderFrame; +} + +namespace QtWebEngineCore { + +class QtRenderFrameObserver : public content::RenderFrameObserver { +public: + explicit QtRenderFrameObserver(content::RenderFrame* render_frame); + ~QtRenderFrameObserver(); + +#if defined(ENABLE_PLUGINS) + void DidCreatePepperPlugin(content::RendererPpapiHost* host) override; +#endif + +private: + DISALLOW_COPY_AND_ASSIGN(QtRenderFrameObserver); +}; + +} // namespace QtWebEngineCore + +#endif // QT_RENDER_FRAME_OBSERVER_H diff --git a/src/core/renderer/qt_render_view_observer.cpp b/src/core/renderer/qt_render_view_observer.cpp index 83534dadd..ba91e54ae 100644 --- a/src/core/renderer/qt_render_view_observer.cpp +++ b/src/core/renderer/qt_render_view_observer.cpp @@ -65,6 +65,11 @@ void QtRenderViewObserver::onFetchDocumentInnerText(quint64 requestId) render_view()->GetWebView()->mainFrame()->contentAsText(std::numeric_limits<std::size_t>::max()))); } +void QtRenderViewObserver::onSetBackgroundColor(quint32 color) +{ + render_view()->GetWebView()->setBaseBackgroundColor(color); +} + void QtRenderViewObserver::OnFirstVisuallyNonEmptyLayout() { Send(new QtRenderViewObserverHost_DidFirstVisuallyNonEmptyLayout(routing_id())); @@ -76,6 +81,7 @@ bool QtRenderViewObserver::OnMessageReceived(const IPC::Message& message) IPC_BEGIN_MESSAGE_MAP(QtRenderViewObserver, message) IPC_MESSAGE_HANDLER(QtRenderViewObserver_FetchDocumentMarkup, onFetchDocumentMarkup) IPC_MESSAGE_HANDLER(QtRenderViewObserver_FetchDocumentInnerText, onFetchDocumentInnerText) + IPC_MESSAGE_HANDLER(QtRenderViewObserver_SetBackgroundColor, onSetBackgroundColor) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; diff --git a/src/core/renderer/qt_render_view_observer.h b/src/core/renderer/qt_render_view_observer.h index cb77cd0c9..3f7829a92 100644 --- a/src/core/renderer/qt_render_view_observer.h +++ b/src/core/renderer/qt_render_view_observer.h @@ -47,6 +47,7 @@ public: private: void onFetchDocumentMarkup(quint64 requestId); void onFetchDocumentInnerText(quint64 requestId); + void onSetBackgroundColor(quint32 color); void OnFirstVisuallyNonEmptyLayout() Q_DECL_OVERRIDE; diff --git a/src/core/resources/resources.gyp b/src/core/resources/resources.gyp index 4d653df12..6293cdf3b 100644 --- a/src/core/resources/resources.gyp +++ b/src/core/resources/resources.gyp @@ -15,7 +15,7 @@ }, 'dependencies': [ '<(chromium_src_dir)/content/app/strings/content_strings.gyp:content_strings', - '<(chromium_src_dir)/webkit/blink_resources.gyp:blink_resources', + '<(chromium_src_dir)/blink/public/blink_resources.gyp:blink_resources', '<(chromium_src_dir)/content/browser/devtools/devtools_resources.gyp:devtools_resources', '../chrome_qt.gyp:chrome_resources', ], @@ -29,7 +29,7 @@ 'variables': { 'pak_inputs': [ '<(SHARED_INTERMEDIATE_DIR)/net/net_resources.pak', - '<(SHARED_INTERMEDIATE_DIR)/webkit/devtools_resources.pak', + '<(SHARED_INTERMEDIATE_DIR)/blink/devtools_resources.pak', '<(SHARED_INTERMEDIATE_DIR)/content/content_resources.pak', '<(SHARED_INTERMEDIATE_DIR)/blink/public/resources/blink_resources.pak', '<(SHARED_INTERMEDIATE_DIR)/ui/resources/webui_resources.pak', diff --git a/src/core/type_conversion.h b/src/core/type_conversion.h index 66fcd4dd0..9e5461888 100644 --- a/src/core/type_conversion.h +++ b/src/core/type_conversion.h @@ -41,15 +41,17 @@ #include <QDateTime> #include <QDir> #include <QMatrix4x4> +#include <QNetworkCookie> #include <QRect> #include <QString> #include <QUrl> #include "base/files/file_path.h" #include "base/time/time.h" #include "content/public/common/file_chooser_file_info.h" +#include "net/cookies/canonical_cookie.h" #include "third_party/skia/include/utils/SkMatrix44.h" #include "third_party/skia/include/core/SkColor.h" -#include "ui/gfx/rect.h" +#include "ui/gfx/geometry/rect.h" #include "url/gurl.h" namespace QtWebEngineCore { @@ -92,6 +94,11 @@ inline QPoint toQt(const gfx::Point &point) return QPoint(point.x(), point.y()); } +inline gfx::Point toGfx(const QPoint& point) +{ + return gfx::Point(point.x(), point.y()); +} + inline QRect toQt(const gfx::Rect &rect) { return QRect(rect.x(), rect.y(), rect.width(), rect.height()); @@ -122,6 +129,11 @@ inline QColor toQt(const SkColor &c) return QColor(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c), SkColorGetA(c)); } +inline SkColor toSk(const QColor &c) +{ + return c.rgba(); +} + inline QMatrix4x4 toQt(const SkMatrix44 &m) { QMatrix4x4 qtMatrix( @@ -142,6 +154,18 @@ inline base::Time toTime(const QDateTime &dateTime) { return base::Time::FromInternalValue(dateTime.toMSecsSinceEpoch()); } +inline QNetworkCookie toQt(const net::CanonicalCookie & cookie) +{ + QNetworkCookie qCookie = QNetworkCookie(QByteArray::fromStdString(cookie.Name()), QByteArray::fromStdString(cookie.Value())); + qCookie.setDomain(toQt(cookie.Domain())); + if (!cookie.ExpiryDate().is_null()) + qCookie.setExpirationDate(toQt(cookie.ExpiryDate())); + qCookie.setHttpOnly(cookie.IsHttpOnly()); + qCookie.setPath(toQt(cookie.Path())); + qCookie.setSecure(cookie.IsSecure()); + return qCookie; +} + inline base::FilePath::StringType toFilePathString(const QString &str) { #if defined(OS_WIN) diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp index 10923e4cb..a50fcbe0e 100644 --- a/src/core/url_request_context_getter_qt.cpp +++ b/src/core/url_request_context_getter_qt.cpp @@ -41,7 +41,6 @@ #include "base/threading/worker_pool.h" #include "base/threading/sequenced_worker_pool.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/cookie_crypto_delegate.h" #include "content/public/browser/cookie_store_factory.h" #include "content/public/common/content_switches.h" #include "net/base/cache_type.h" @@ -70,9 +69,14 @@ #include "browser_context_adapter.h" #include "custom_protocol_handler.h" #include "custom_url_scheme_handler.h" +#include "cookie_monster_delegate_qt.h" #include "content_client_qt.h" #include "network_delegate_qt.h" +#include "proxy_config_service_qt.h" +#include "proxy_resolver_qt.h" #include "qrc_protocol_handler_qt.h" +#include "qwebenginecookiestoreclient.h" +#include "qwebenginecookiestoreclient_p.h" #include "type_conversion.h" namespace QtWebEngineCore { @@ -84,6 +88,7 @@ using content::BrowserThread; URLRequestContextGetterQt::URLRequestContextGetterQt(BrowserContextAdapter *browserContext, content::ProtocolHandlerMap *protocolHandlers) : m_ignoreCertificateErrors(false) , m_browserContext(browserContext) + , m_cookieDelegate(new CookieMonsterDelegateQt()) { std::swap(m_protocolHandlers, *protocolHandlers); @@ -100,7 +105,7 @@ net::URLRequestContext *URLRequestContextGetterQt::GetURLRequestContext() if (!m_urlRequestContext) { m_urlRequestContext.reset(new net::URLRequestContext()); - m_networkDelegate.reset(new NetworkDelegateQt); + m_networkDelegate.reset(new NetworkDelegateQt(this)); m_urlRequestContext->set_network_delegate(m_networkDelegate.get()); generateStorage(); @@ -117,10 +122,10 @@ void URLRequestContextGetterQt::updateStorageSettings() // We must create the proxy config service on the UI loop on Linux because it // must synchronously run on the glib message loop. This will be passed to // the URLRequestContextStorage on the IO thread in GetURLRequestContext(). - m_proxyConfigService = net::ProxyService::CreateSystemProxyConfigService( + m_proxyConfigService = new ProxyConfigServiceQt(net::ProxyService::CreateSystemProxyConfigService( content::BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), content::BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE) - ); + )); if (m_storage) content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateStorage, this)); } @@ -150,26 +155,23 @@ void URLRequestContextGetterQt::generateStorage() generateCookieStore(); generateUserAgent(); - m_storage->set_channel_id_service(new net::ChannelIDService( + m_storage->set_channel_id_service(scoped_ptr<net::ChannelIDService>(new net::ChannelIDService( new net::DefaultChannelIDStore(NULL), - base::WorkerPool::GetTaskRunner(true))); + base::WorkerPool::GetTaskRunner(true)))); m_storage->set_cert_verifier(net::CertVerifier::CreateDefault()); scoped_ptr<net::HostResolver> host_resolver(net::HostResolver::CreateDefaultResolver(NULL)); // The System Proxy Resolver has issues on Windows with unconfigured network cards, - // which is why we want to use the v8 one. However, V8ProxyResolver doesn't work reliably with - // --single-process (See also the warnings in net/proxy/proxy_resolver_v8.h). - base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); - if (command_line.HasSwitch(switches::kSingleProcess)) { - m_storage->set_proxy_service( - net::ProxyService::CreateUsingSystemProxyResolver(proxyConfigService, 0, NULL)); + // which is why we want to use the v8 one + if (ProxyResolverQt::useProxyResolverQt()) { + scoped_ptr<ProxyResolverFactoryQt> factory(new ProxyResolverFactoryQt(false)); + m_storage->set_proxy_service(new net::ProxyService(proxyConfigService, factory.Pass(), nullptr)); } else { if (!m_dhcpProxyScriptFetcherFactory) m_dhcpProxyScriptFetcherFactory.reset(new net::DhcpProxyScriptFetcherFactory); - net::ProxyResolverV8::EnsureIsolateCreated(); m_storage->set_proxy_service(net::CreateProxyServiceUsingV8ProxyResolver( proxyConfigService, new net::ProxyScriptFetcherImpl(m_urlRequestContext.get()), @@ -206,6 +208,8 @@ void URLRequestContextGetterQt::generateCookieStore() // Unset it first to get a chance to destroy and flush the old cookie store before before opening a new on possibly the same file. m_storage->set_cookie_store(0); + m_cookieDelegate->setCookieMonster(0); + m_cookieDelegate->setClient(m_browserContext->cookieStoreClient()); net::CookieStore* cookieStore = 0; switch (m_browserContext->persistentCookiesPolicy()) { @@ -214,7 +218,8 @@ void URLRequestContextGetterQt::generateCookieStore() content::CreateCookieStore(content::CookieStoreConfig( base::FilePath(), content::CookieStoreConfig::EPHEMERAL_SESSION_COOKIES, - NULL, NULL) + NULL, + m_cookieDelegate.get()) ); break; case BrowserContextAdapter::AllowPersistentCookies: @@ -222,7 +227,8 @@ void URLRequestContextGetterQt::generateCookieStore() content::CreateCookieStore(content::CookieStoreConfig( toFilePath(m_browserContext->cookiesPath()), content::CookieStoreConfig::PERSISTANT_SESSION_COOKIES, - NULL, NULL) + NULL, + m_cookieDelegate.get()) ); break; case BrowserContextAdapter::ForcePersistentCookies: @@ -230,11 +236,16 @@ void URLRequestContextGetterQt::generateCookieStore() content::CreateCookieStore(content::CookieStoreConfig( toFilePath(m_browserContext->cookiesPath()), content::CookieStoreConfig::RESTORED_SESSION_COOKIES, - NULL, NULL) + NULL, + m_cookieDelegate.get()) ); break; } m_storage->set_cookie_store(cookieStore); + + net::CookieMonster * const cookieMonster = cookieStore->GetCookieMonster(); + cookieMonster->SetCookieableSchemes(kCookieableSchemes, arraysize(kCookieableSchemes)); + m_cookieDelegate->setCookieMonster(cookieMonster); } void URLRequestContextGetterQt::updateUserAgent() @@ -243,13 +254,32 @@ void URLRequestContextGetterQt::updateUserAgent() content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestContextGetterQt::generateUserAgent, this)); } +class HttpUserAgentSettingsQt : public net::HttpUserAgentSettings +{ + const BrowserContextAdapter *m_browserContext; +public: + HttpUserAgentSettingsQt(const BrowserContextAdapter *ctx) + : m_browserContext(ctx) + { + } + + std::string GetAcceptLanguage() const Q_DECL_OVERRIDE + { + return m_browserContext->httpAcceptLanguage().toStdString(); + } + + std::string GetUserAgent() const Q_DECL_OVERRIDE + { + return m_browserContext->httpUserAgent().toStdString(); + } +}; + void URLRequestContextGetterQt::generateUserAgent() { Q_ASSERT(m_urlRequestContext); Q_ASSERT(m_storage); - m_storage->set_http_user_agent_settings( - new net::StaticHttpUserAgentSettings("en-us,en", m_browserContext->httpUserAgent().toStdString())); + m_storage->set_http_user_agent_settings(new HttpUserAgentSettingsQt(m_browserContext)); } void URLRequestContextGetterQt::updateHttpCache() diff --git a/src/core/url_request_context_getter_qt.h b/src/core/url_request_context_getter_qt.h index 38cfd7957..c7a4366ec 100644 --- a/src/core/url_request_context_getter_qt.h +++ b/src/core/url_request_context_getter_qt.h @@ -49,12 +49,14 @@ #include "net/url_request/url_request_job_factory_impl.h" #include "net/proxy/dhcp_proxy_script_fetcher_factory.h" +#include "cookie_monster_delegate_qt.h" +#include "network_delegate_qt.h" + #include "qglobal.h" #include <qatomic.h> namespace net { class MappedHostResolver; -class NetworkDelegate; class ProxyConfigService; } @@ -93,10 +95,12 @@ private: QAtomicPointer<net::ProxyConfigService> m_proxyConfigService; scoped_ptr<net::URLRequestContext> m_urlRequestContext; - scoped_ptr<net::NetworkDelegate> m_networkDelegate; + scoped_ptr<NetworkDelegateQt> m_networkDelegate; scoped_ptr<net::URLRequestContextStorage> m_storage; scoped_ptr<net::URLRequestJobFactoryImpl> m_jobFactory; scoped_ptr<net::DhcpProxyScriptFetcherFactory> m_dhcpProxyScriptFetcherFactory; + scoped_refptr<CookieMonsterDelegateQt> m_cookieDelegate; + friend class NetworkDelegateQt; }; } // namespace QtWebEngineCore diff --git a/src/core/user_script_controller_host.cpp b/src/core/user_script_controller_host.cpp index 227a639b1..d57518275 100644 --- a/src/core/user_script_controller_host.cpp +++ b/src/core/user_script_controller_host.cpp @@ -52,9 +52,12 @@ namespace QtWebEngineCore { class UserScriptControllerHost::WebContentsObserverHelper : public content::WebContentsObserver { public: WebContentsObserverHelper(UserScriptControllerHost *, content::WebContents *); - virtual void AboutToNavigateRenderView(content::RenderViewHost* renderViewHost) Q_DECL_OVERRIDE; - virtual void WebContentsDestroyed() Q_DECL_OVERRIDE; + // WebContentsObserver overrides: + void RenderViewCreated(content::RenderViewHost *renderViewHost) override; + void RenderViewHostChanged(content::RenderViewHost *oldHost, content::RenderViewHost *newHost) override; + void WebContentsDestroyed() override; + private: UserScriptControllerHost *m_controllerHost; }; @@ -65,13 +68,23 @@ UserScriptControllerHost::WebContentsObserverHelper::WebContentsObserverHelper(U { } -void UserScriptControllerHost::WebContentsObserverHelper::AboutToNavigateRenderView(content::RenderViewHost *renderViewHost) +void UserScriptControllerHost::WebContentsObserverHelper::RenderViewCreated(content::RenderViewHost *renderViewHost) { content::WebContents *contents = web_contents(); Q_FOREACH (const UserScript &script, m_controllerHost->m_perContentsScripts.value(contents)) renderViewHost->Send(new RenderViewObserverHelper_AddScript(renderViewHost->GetRoutingID(), script.data())); } +void UserScriptControllerHost::WebContentsObserverHelper::RenderViewHostChanged(content::RenderViewHost *oldHost, + content::RenderViewHost *newHost) +{ + oldHost->Send(new RenderViewObserverHelper_ClearScripts(oldHost->GetRoutingID())); + + content::WebContents *contents = web_contents(); + Q_FOREACH (const UserScript &script, m_controllerHost->m_perContentsScripts.value(contents)) + newHost->Send(new RenderViewObserverHelper_AddScript(newHost->GetRoutingID(), script.data())); +} + void UserScriptControllerHost::WebContentsObserverHelper::WebContentsDestroyed() { m_controllerHost->webContentsDestroyed(web_contents()); diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 8c13035e8..999fc881c 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -46,6 +46,7 @@ #include "browser_context_qt.h" #include "media_capture_devices_dispatcher.h" #include "qt_render_view_observer_host.h" +#include "qwebenginecallback_p.h" #include "type_conversion.h" #include "web_channel_ipc_transport_host.h" #include "web_contents_adapter_client.h" @@ -57,6 +58,7 @@ #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/child_process_security_policy.h" +#include <content/public/browser/download_manager.h> #include "content/public/browser/host_zoom_map.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/render_view_host.h" @@ -66,7 +68,6 @@ #include "content/public/common/renderer_preferences.h" #include "content/public/common/url_constants.h" #include "content/public/common/web_preferences.h" -#include "ui/shell_dialogs/selected_file_info.h" #include "third_party/WebKit/public/web/WebFindOptions.h" #include <QDir> @@ -165,19 +166,6 @@ static void callbackOnEvaluateJS(WebContentsAdapterClient *adapterClient, quint6 adapterClient->didRunJavaScript(requestId, fromJSValue(result)); } -static QStringList listRecursively(const QDir& dir) { - QStringList ret; - QFileInfoList infoList(dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot |QDir::Hidden)); - Q_FOREACH (const QFileInfo &fileInfo, infoList) { - if (fileInfo.isDir()) { - ret.append(fileInfo.absolutePath() + QStringLiteral("/.")); // Match chromium's behavior. See chrome/browser/file_select_helper.cc - ret.append(listRecursively(QDir(fileInfo.absoluteFilePath()))); - } else - ret.append(fileInfo.absoluteFilePath()); - } - return ret; -} - static content::WebContents *createBlankWebContents(WebContentsAdapterClient *adapterClient, content::BrowserContext *browserContext) { content::WebContents::CreateParams create_params(browserContext, NULL); @@ -217,9 +205,6 @@ static void serializeNavigationHistory(const content::NavigationController &cont output << entry->GetIsOverridingUserAgent(); output << static_cast<qint64>(entry->GetTimestamp().ToInternalValue()); output << entry->GetHttpStatusCode(); - // If you want to navigate a named frame in Chrome, you will first need to - // add support for persisting it. It is currently only used for layout tests. - CHECK(entry->GetFrameToNavigate().empty()); } } } @@ -323,7 +308,7 @@ WebContentsAdapterPrivate::WebContentsAdapterPrivate() : engineContext(WebEngineContext::current()) , webChannel(0) , adapterClient(0) - , nextRequestId(1) + , nextRequestId(CallbackDirectory::ReservedCallbackIdsEnd) , lastFindRequestId(0) { } @@ -495,6 +480,7 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT params.base_url_for_data_url = toGurl(baseUrl); params.virtual_url_for_data_url = baseUrl.isEmpty() ? GURL(url::kAboutBlankURL) : toGurl(baseUrl); params.can_load_local_resources = true; + params.transition_type = ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_API); d->webContents->GetController().LoadURLWithParams(params); } @@ -772,6 +758,38 @@ void WebContentsAdapter::updateWebPreferences(const content::WebPreferences & we d->webContents->GetRenderViewHost()->UpdateWebkitPreferences(webPreferences); } +void WebContentsAdapter::download(const QUrl &url, const QString &suggestedFileName) +{ + content::BrowserContext *bctx = webContents()->GetBrowserContext(); + content::DownloadManager *dlm = content::BrowserContext::GetDownloadManager(bctx); + if (!dlm) + return; + + scoped_ptr<content::DownloadUrlParameters> params( + content::DownloadUrlParameters::FromWebContents(webContents(), toGurl(url))); + params->set_suggested_name(toString16(suggestedFileName)); + dlm->DownloadUrl(params.Pass()); +} + +void WebContentsAdapter::copyImageAt(const QPoint &location) +{ + Q_D(WebContentsAdapter); + d->webContents->GetRenderViewHost()->CopyImageAt(location.x(), location.y()); +} + +ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerNoAction, blink::WebMediaPlayerAction::Unknown) +ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerPlay, blink::WebMediaPlayerAction::Play) +ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerMute, blink::WebMediaPlayerAction::Mute) +ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerLoop, blink::WebMediaPlayerAction::Loop) +ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerControls, blink::WebMediaPlayerAction::Controls) + +void WebContentsAdapter::executeMediaPlayerActionAt(const QPoint &location, MediaPlayerAction action, bool enable) +{ + Q_D(WebContentsAdapter); + blink::WebMediaPlayerAction blinkAction((blink::WebMediaPlayerAction::Type)action, enable); + d->webContents->GetRenderViewHost()->ExecuteMediaPlayerActionAtLocation(toGfx(location), blinkAction); +} + void WebContentsAdapter::wasShown() { Q_D(WebContentsAdapter); @@ -793,7 +811,7 @@ void WebContentsAdapter::grantMediaAccessPermission(const QUrl &securityOrigin, void WebContentsAdapter::runGeolocationRequestCallback(const QUrl &securityOrigin, bool allowed) { Q_D(WebContentsAdapter); - d->webContentsDelegate->geolocationPermissionReply(securityOrigin, allowed); + d->browserContextAdapter->permissionRequestReply(securityOrigin, BrowserContextAdapter::GeolocationPermission, allowed); } void WebContentsAdapter::grantMouseLockPermission(bool granted) @@ -820,21 +838,11 @@ void WebContentsAdapter::dpiScaleChanged() impl->NotifyScreenInfoChanged(); } -ASSERT_ENUMS_MATCH(WebContentsAdapterClient::Open, content::FileChooserParams::Open) -ASSERT_ENUMS_MATCH(WebContentsAdapterClient::OpenMultiple, content::FileChooserParams::OpenMultiple) -ASSERT_ENUMS_MATCH(WebContentsAdapterClient::UploadFolder, content::FileChooserParams::UploadFolder) -ASSERT_ENUMS_MATCH(WebContentsAdapterClient::Save, content::FileChooserParams::Save) - -void WebContentsAdapter::filesSelectedInChooser(const QStringList &fileList, WebContentsAdapterClient::FileChooserMode mode) +void WebContentsAdapter::backgroundColorChanged() { Q_D(WebContentsAdapter); - content::RenderViewHost *rvh = d->webContents->GetRenderViewHost(); - Q_ASSERT(rvh); - QStringList files(fileList); - if (mode == WebContentsAdapterClient::UploadFolder && !fileList.isEmpty() - && QFileInfo(fileList.first()).isDir()) // Enumerate the directory - files = listRecursively(QDir(fileList.first())); - rvh->FilesSelectedInChooser(toVector<content::FileChooserFileInfo>(files), static_cast<content::FileChooserParams::Mode>(mode)); + if (content::RenderWidgetHostView *rwhv = d->webContents->GetRenderWidgetHostView()) + rwhv->SetBackgroundColor(toSk(d->adapterClient->backgroundColor())); } content::WebContents *WebContentsAdapter::webContents() const diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h index 5ea55c1b8..902cc61ff 100644 --- a/src/core/web_contents_adapter.h +++ b/src/core/web_contents_adapter.h @@ -104,7 +104,6 @@ public: void serializeNavigationHistory(QDataStream &output); void setZoomFactor(qreal); qreal currentZoomFactor() const; - void filesSelectedInChooser(const QStringList &fileList, WebContentsAdapterClient::FileChooserMode); void runJavaScript(const QString &javaScript); quint64 runJavaScriptCallbackResult(const QString &javaScript); quint64 fetchDocumentMarkup(); @@ -112,6 +111,19 @@ public: quint64 findText(const QString &subString, bool caseSensitively, bool findBackward); void stopFinding(); void updateWebPreferences(const content::WebPreferences &webPreferences); + void download(const QUrl &url, const QString &suggestedFileName); + + // Must match blink::WebMediaPlayerAction::Type. + enum MediaPlayerAction { + MediaPlayerNoAction, + MediaPlayerPlay, + MediaPlayerMute, + MediaPlayerLoop, + MediaPlayerControls, + MediaPlayerTypeLast = MediaPlayerControls + }; + void copyImageAt(const QPoint &location); + void executeMediaPlayerActionAt(const QPoint &location, MediaPlayerAction action, bool enable); void wasShown(); void wasHidden(); @@ -120,6 +132,7 @@ public: void grantMouseLockPermission(bool granted); void dpiScaleChanged(); + void backgroundColorChanged(); QAccessibleInterface *browserAccessible(); BrowserContextQt* browserContext(); BrowserContextAdapter* browserContextAdapter(); diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index 3ed3ab9ab..86b5d1b79 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -53,6 +53,7 @@ QT_FORWARD_DECLARE_CLASS(CertificateErrorController) namespace QtWebEngineCore { class BrowserContextAdapter; +class FilePickerController; class JavaScriptDialogController; class RenderWidgetHostViewQt; class RenderWidgetHostViewQtDelegate; @@ -65,10 +66,55 @@ class WebEngineSettings; class WebEngineContextMenuData { public: + WebEngineContextMenuData() + : mediaType(MediaTypeNone) + , hasImageContent(false) + , mediaFlags(0) + { + } + + // Must match blink::WebContextMenuData::MediaType: + enum MediaType { + // No special node is in context. + MediaTypeNone, + // An image node is selected. + MediaTypeImage, + // A video node is selected. + MediaTypeVideo, + // An audio node is selected. + MediaTypeAudio, + // A canvas node is selected. + MediaTypeCanvas, + // A file node is selected. + MediaTypeFile, + // A plugin node is selected. + MediaTypePlugin, + MediaTypeLast = MediaTypePlugin + }; + // Must match blink::WebContextMenuData::MediaFlags: + enum MediaFlags { + MediaNone = 0x0, + MediaInError = 0x1, + MediaPaused = 0x2, + MediaMuted = 0x4, + MediaLoop = 0x8, + MediaCanSave = 0x10, + MediaHasAudio = 0x20, + MediaCanToggleControls = 0x40, + MediaControls = 0x80, + MediaCanPrint = 0x100, + MediaCanRotate = 0x200, + }; + QPoint pos; QUrl linkUrl; QString linkText; QString selectedText; + QUrl mediaUrl; + MediaType mediaType; + bool hasImageContent; + uint mediaFlags; + QString suggestedFileName; // Some likely candidates for future additions as we add support for the related actions: // bool isImageBlocked; // bool isEditable; @@ -104,14 +150,6 @@ public: InternalAuthorizationDialog = 0x10, }; - // Must match the ones in file_chooser_params.h - enum FileChooserMode { - Open, - OpenMultiple, - UploadFolder, - Save - }; - enum NavigationRequestAction { AcceptRequest, // Make room in the valid range of the enum for extra actions exposed in Experimental. @@ -119,7 +157,7 @@ public: }; enum NavigationType { - LinkClickedNavigation, + LinkNavigation, TypedNavigation, FormSubmittedNavigation, BackForwardNavigation, @@ -152,6 +190,7 @@ public: virtual void selectionChanged() = 0; virtual QRectF viewportRect() const = 0; virtual qreal dpiScale() const = 0; + virtual QColor backgroundColor() const = 0; virtual void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) = 0; virtual void loadCommitted() = 0; virtual void loadVisuallyCommitted() = 0; @@ -165,7 +204,7 @@ public: virtual void requestFullScreen(bool) = 0; virtual bool isFullScreen() const = 0; virtual void javascriptDialog(QSharedPointer<JavaScriptDialogController>) = 0; - virtual void runFileChooser(FileChooserMode, const QString &defaultFileName, const QStringList &acceptedMimeTypes) = 0; + virtual void runFileChooser(FilePickerController *controller) = 0; virtual void didRunJavaScript(quint64 requestId, const QVariant& result) = 0; virtual void didFetchDocumentMarkup(quint64 requestId, const QString& result) = 0; virtual void didFetchDocumentInnerText(quint64 requestId, const QString& result) = 0; diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index f9db91b3e..93fabf15a 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -41,6 +41,7 @@ #include "web_contents_delegate_qt.h" #include "browser_context_adapter.h" +#include "file_picker_controller.h" #include "media_capture_devices_dispatcher.h" #include "type_conversion.h" #include "web_contents_adapter_client.h" @@ -107,7 +108,7 @@ content::WebContents *WebContentsDelegateQt::OpenURLFromTab(content::WebContents return target; } -void WebContentsDelegateQt::NavigationStateChanged(const content::WebContents* source, content::InvalidateTypes changed_flags) +void WebContentsDelegateQt::NavigationStateChanged(content::WebContents* source, content::InvalidateTypes changed_flags) { if (changed_flags & content::INVALIDATE_TYPE_URL) m_viewClient->urlChanged(toQt(source->GetVisibleURL())); @@ -126,7 +127,7 @@ void WebContentsDelegateQt::AddNewContents(content::WebContents* source, content void WebContentsDelegateQt::CloseContents(content::WebContents *source) { m_viewClient->close(); - GetJavaScriptDialogManager()->CancelActiveAndPendingDialogs(source); + GetJavaScriptDialogManager(source)->CancelActiveAndPendingDialogs(source); } void WebContentsDelegateQt::LoadProgressChanged(content::WebContents* source, double progress) @@ -228,36 +229,47 @@ void WebContentsDelegateQt::DidUpdateFaviconURL(const std::vector<content::Favic } } -content::JavaScriptDialogManager *WebContentsDelegateQt::GetJavaScriptDialogManager() +content::JavaScriptDialogManager *WebContentsDelegateQt::GetJavaScriptDialogManager(content::WebContents *) { return JavaScriptDialogManagerQt::GetInstance(); } -void WebContentsDelegateQt::ToggleFullscreenModeForTab(content::WebContents* web_contents, bool enter_fullscreen) +void WebContentsDelegateQt::EnterFullscreenModeForTab(content::WebContents *web_contents, const GURL& origin) { - if (m_viewClient->isFullScreen() != enter_fullscreen) { - m_viewClient->requestFullScreen(enter_fullscreen); + Q_UNUSED(origin); // FIXME + if (!m_viewClient->isFullScreen()) { + m_viewClient->requestFullScreen(true); web_contents->GetRenderViewHost()->WasResized(); } } +void WebContentsDelegateQt::ExitFullscreenModeForTab(content::WebContents *web_contents) +{ + if (m_viewClient->isFullScreen()) { + m_viewClient->requestFullScreen(false); + web_contents->GetRenderViewHost()->WasResized(); + } +} + bool WebContentsDelegateQt::IsFullscreenForTabOrPending(const content::WebContents* web_contents) const { return m_viewClient->isFullScreen(); } -ASSERT_ENUMS_MATCH(WebContentsAdapterClient::Open, content::FileChooserParams::Open) -ASSERT_ENUMS_MATCH(WebContentsAdapterClient::Save, content::FileChooserParams::Save) +ASSERT_ENUMS_MATCH(FilePickerController::Open, content::FileChooserParams::Open) +ASSERT_ENUMS_MATCH(FilePickerController::OpenMultiple, content::FileChooserParams::OpenMultiple) +ASSERT_ENUMS_MATCH(FilePickerController::UploadFolder, content::FileChooserParams::UploadFolder) +ASSERT_ENUMS_MATCH(FilePickerController::Save, content::FileChooserParams::Save) void WebContentsDelegateQt::RunFileChooser(content::WebContents *web_contents, const content::FileChooserParams ¶ms) { - Q_UNUSED(web_contents) QStringList acceptedMimeTypes; acceptedMimeTypes.reserve(params.accept_types.size()); for (std::vector<base::string16>::const_iterator it = params.accept_types.begin(); it < params.accept_types.end(); ++it) acceptedMimeTypes.append(toQt(*it)); - m_viewClient->runFileChooser(static_cast<WebContentsAdapterClient::FileChooserMode>(params.mode), toQt(params.default_file_name.value()), acceptedMimeTypes); + FilePickerController *controller = new FilePickerController(static_cast<FilePickerController::FileChooserMode>(params.mode), web_contents, toQt(params.default_file_name.value()), acceptedMimeTypes); + m_viewClient->runFileChooser(controller); } bool WebContentsDelegateQt::AddMessageToConsole(content::WebContents *source, int32 level, const base::string16 &message, int32 line_no, const base::string16 &source_id) @@ -334,28 +346,9 @@ void WebContentsDelegateQt::allowCertificateError(const QSharedPointer<Certifica m_viewClient->allowCertificateError(errorController); } -void WebContentsDelegateQt::requestGeolocationPermission(const GURL &requestingFrameOrigin, const base::Callback<void (bool)> &resultCallback) +void WebContentsDelegateQt::requestGeolocationPermission(const QUrl &requestingOrigin) { - QUrl url = toQt(requestingFrameOrigin); - bool newRequest = !m_geolocationPermissionRequests.contains(url); - m_geolocationPermissionRequests[url] = resultCallback; - if (newRequest) - m_viewClient->runGeolocationPermissionRequest(url); -} - -void WebContentsDelegateQt::cancelGeolocationPermissionRequest(const GURL &requestingFrameOrigin) -{ - m_geolocationPermissionRequests.remove(toQt(requestingFrameOrigin)); - // FIXME: Tell the API layer to cancel the permission request? -} - -void WebContentsDelegateQt::geolocationPermissionReply(const QUrl &origin, bool permission) -{ - auto it = m_geolocationPermissionRequests.find(origin); - if (it != m_geolocationPermissionRequests.end()) { - (*it).Run(permission); - m_geolocationPermissionRequests.erase(it); - } + m_viewClient->runGeolocationPermissionRequest(requestingOrigin); } void WebContentsDelegateQt::ShowValidationMessage(content::WebContents *web_contents, const gfx::Rect &anchor_in_root_view, const base::string16 &main_text, const base::string16 &sub_text) diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h index 254177d24..b983738e9 100644 --- a/src/core/web_contents_delegate_qt.h +++ b/src/core/web_contents_delegate_qt.h @@ -39,6 +39,7 @@ #include "content/public/browser/web_contents_delegate.h" #include "content/public/browser/web_contents_observer.h" +#include "content/public/common/permission_status.mojom.h" #include "base/callback.h" @@ -72,13 +73,14 @@ public: // WebContentsDelegate overrides virtual content::WebContents *OpenURLFromTab(content::WebContents *source, const content::OpenURLParams ¶ms) Q_DECL_OVERRIDE; - virtual void NavigationStateChanged(const content::WebContents* source, content::InvalidateTypes changed_flags) Q_DECL_OVERRIDE; + virtual void NavigationStateChanged(content::WebContents* source, content::InvalidateTypes changed_flags) Q_DECL_OVERRIDE; virtual void AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture, bool* was_blocked) Q_DECL_OVERRIDE; virtual void CloseContents(content::WebContents *source) Q_DECL_OVERRIDE; virtual void LoadProgressChanged(content::WebContents* source, double progress) Q_DECL_OVERRIDE; virtual void HandleKeyboardEvent(content::WebContents *source, const content::NativeWebKeyboardEvent &event) Q_DECL_OVERRIDE; - virtual content::JavaScriptDialogManager *GetJavaScriptDialogManager() Q_DECL_OVERRIDE; - virtual void ToggleFullscreenModeForTab(content::WebContents* web_contents, bool enter_fullscreen) Q_DECL_OVERRIDE; + virtual content::JavaScriptDialogManager *GetJavaScriptDialogManager(content::WebContents *source) Q_DECL_OVERRIDE; + virtual void EnterFullscreenModeForTab(content::WebContents* web_contents, const GURL& origin) Q_DECL_OVERRIDE; + virtual void ExitFullscreenModeForTab(content::WebContents*) Q_DECL_OVERRIDE; virtual bool IsFullscreenForTabOrPending(const content::WebContents* web_contents) const Q_DECL_OVERRIDE; virtual void RunFileChooser(content::WebContents *, const content::FileChooserParams ¶ms) Q_DECL_OVERRIDE; virtual bool AddMessageToConsole(content::WebContents* source, int32 level, const base::string16& message, int32 line_no, const base::string16& source_id) Q_DECL_OVERRIDE; @@ -101,15 +103,11 @@ public: void overrideWebPreferences(content::WebContents *, content::WebPreferences*); void allowCertificateError(const QSharedPointer<CertificateErrorController> &) ; - void requestGeolocationPermission(const GURL &requestingFrameOrigin, const base::Callback<void (bool)> &resultCallback); - void cancelGeolocationPermissionRequest(const GURL &requestingFrameOrigin); - void geolocationPermissionReply(const QUrl&, bool permission); + void requestGeolocationPermission(const QUrl &requestingOrigin); private: WebContentsAdapter *createWindow(content::WebContents *new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture); - QHash<QUrl, base::Callback<void (bool)> > m_geolocationPermissionRequests; - WebContentsAdapterClient *m_viewClient; QString m_lastSearchedString; int m_lastReceivedFindReply; diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp index af0c1fe38..c32753435 100644 --- a/src/core/web_contents_view_qt.cpp +++ b/src/core/web_contents_view_qt.cpp @@ -53,8 +53,10 @@ void WebContentsViewQt::initialize(WebContentsAdapterClient* client) m_factoryClient = client; // Check if a RWHV was created before the initialization. - if (m_webContents->GetRenderWidgetHostView()) - static_cast<RenderWidgetHostViewQt *>(m_webContents->GetRenderWidgetHostView())->setAdapterClient(client); + if (auto rwhv = static_cast<RenderWidgetHostViewQt *>(m_webContents->GetRenderWidgetHostView())) { + rwhv->setAdapterClient(client); + rwhv->SetBackgroundColor(toSk(client->backgroundColor())); + } } content::RenderWidgetHostViewBase* WebContentsViewQt::CreateViewForWidget(content::RenderWidgetHost* render_widget_host, bool is_guest_view_hack) @@ -82,6 +84,14 @@ content::RenderWidgetHostViewBase* WebContentsViewQt::CreateViewForPopupWidget(c return view; } +void WebContentsViewQt::RenderViewCreated(content::RenderViewHost* host) +{ + // The render process is done creating the RenderView and it's ready to be routed + // messages at this point. + if (m_client) + host->GetView()->SetBackgroundColor(toSk(m_client->backgroundColor())); +} + void WebContentsViewQt::CreateView(const gfx::Size& initial_size, gfx::NativeView context) { // This is passed through content::WebContents::CreateParams::context either as the native view's client @@ -111,6 +121,26 @@ void WebContentsViewQt::SetInitialFocus() Focus(); } +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeNone, blink::WebContextMenuData::MediaTypeNone) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeImage, blink::WebContextMenuData::MediaTypeImage) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeVideo, blink::WebContextMenuData::MediaTypeVideo) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeAudio, blink::WebContextMenuData::MediaTypeAudio) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeCanvas, blink::WebContextMenuData::MediaTypeCanvas) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeFile, blink::WebContextMenuData::MediaTypeFile) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypePlugin, blink::WebContextMenuData::MediaTypePlugin) + +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaNone, blink::WebContextMenuData::MediaNone) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaInError, blink::WebContextMenuData::MediaInError) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaPaused, blink::WebContextMenuData::MediaPaused) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaMuted, blink::WebContextMenuData::MediaMuted) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaLoop, blink::WebContextMenuData::MediaLoop) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanSave, blink::WebContextMenuData::MediaCanSave) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaHasAudio, blink::WebContextMenuData::MediaHasAudio) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanToggleControls, blink::WebContextMenuData::MediaCanToggleControls) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaControls, blink::WebContextMenuData::MediaControls) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanPrint, blink::WebContextMenuData::MediaCanPrint) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanRotate, blink::WebContextMenuData::MediaCanRotate) + static WebEngineContextMenuData fromParams(const content::ContextMenuParams ¶ms) { WebEngineContextMenuData ret; @@ -118,6 +148,11 @@ static WebEngineContextMenuData fromParams(const content::ContextMenuParams &par ret.linkUrl = toQt(params.link_url); ret.linkText = toQt(params.link_text.data()); ret.selectedText = toQt(params.selection_text.data()); + ret.mediaUrl = toQt(params.src_url); + ret.mediaType = (WebEngineContextMenuData::MediaType)params.media_type; + ret.hasImageContent = params.has_image_contents; + ret.mediaFlags = params.media_flags; + ret.suggestedFileName = toQt(params.suggested_filename.data()); return ret; } diff --git a/src/core/web_contents_view_qt.h b/src/core/web_contents_view_qt.h index 896955f7d..cbbca2371 100644 --- a/src/core/web_contents_view_qt.h +++ b/src/core/web_contents_view_qt.h @@ -43,8 +43,9 @@ #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host.h" -#include "web_contents_adapter_client.h" +#include "qtwebenginecoreglobal_p.h" #include "render_widget_host_view_qt.h" +#include "web_contents_adapter_client.h" #include "web_contents_delegate_qt.h" #include "web_engine_context.h" @@ -75,7 +76,7 @@ public: virtual void SetPageTitle(const base::string16& title) Q_DECL_OVERRIDE { } - virtual void RenderViewCreated(content::RenderViewHost* host) Q_DECL_OVERRIDE { QT_NOT_YET_IMPLEMENTED } + virtual void RenderViewCreated(content::RenderViewHost* host) Q_DECL_OVERRIDE; virtual void RenderViewSwappedIn(content::RenderViewHost* host) Q_DECL_OVERRIDE { QT_NOT_YET_IMPLEMENTED } diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index 8bc047321..727cfb491 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -202,34 +202,35 @@ WebEngineContext::WebEngineContext() Q_FOREACH (const QString& arg, QCoreApplication::arguments()) args << arg.toUtf8(); + bool useEmbeddedSwitches = args.removeAll("--enable-embedded-switches"); +#if defined(QTWEBENGINE_EMBEDDED_SWITCHES) + useEmbeddedSwitches = !args.removeAll("--disable-embedded-switches"); +#endif + QVector<const char*> argv(args.size()); for (int i = 0; i < args.size(); ++i) argv[i] = args[i].constData(); - CommandLine::Init(argv.size(), argv.constData()); + base::CommandLine::Init(argv.size(), argv.constData()); - CommandLine* parsedCommandLine = CommandLine::ForCurrentProcess(); + base::CommandLine* parsedCommandLine = base::CommandLine::ForCurrentProcess(); parsedCommandLine->AppendSwitchPath(switches::kBrowserSubprocessPath, WebEngineLibraryInfo::getPath(content::CHILD_PROCESS_EXE)); parsedCommandLine->AppendSwitch(switches::kNoSandbox); - parsedCommandLine->AppendSwitch(switches::kDisablePlugins); parsedCommandLine->AppendSwitch(switches::kEnableDelegatedRenderer); parsedCommandLine->AppendSwitch(switches::kEnableThreadedCompositing); parsedCommandLine->AppendSwitch(switches::kInProcessGPU); -#if defined(QTWEBENGINE_MOBILE_SWITCHES) - // Inspired by the Android port's default switches - parsedCommandLine->AppendSwitch(switches::kEnableOverlayScrollbar); - parsedCommandLine->AppendSwitch(switches::kEnablePinch); - parsedCommandLine->AppendSwitch(switches::kEnableViewport); - parsedCommandLine->AppendSwitch(switches::kEnableViewportMeta); - parsedCommandLine->AppendSwitch(switches::kMainFrameResizesAreOrientationChanges); - parsedCommandLine->AppendSwitch(switches::kDisableAcceleratedVideoDecode); - parsedCommandLine->AppendSwitch(switches::kDisableGpuShaderDiskCache); - parsedCommandLine->AppendSwitch(switches::kDisable2dCanvasAntialiasing); - parsedCommandLine->AppendSwitch(switches::kEnableImplSidePainting); - parsedCommandLine->AppendSwitch(cc::switches::kDisableCompositedAntialiasing); - - parsedCommandLine->AppendSwitchASCII(switches::kProfilerTiming, switches::kProfilerTimingDisabledValue); -#endif + if (useEmbeddedSwitches) { + // Inspired by the Android port's default switches + parsedCommandLine->AppendSwitch(switches::kEnableOverlayScrollbar); + parsedCommandLine->AppendSwitch(switches::kEnablePinch); + parsedCommandLine->AppendSwitch(switches::kEnableViewport); + parsedCommandLine->AppendSwitch(switches::kMainFrameResizesAreOrientationChanges); + parsedCommandLine->AppendSwitch(switches::kDisableAcceleratedVideoDecode); + parsedCommandLine->AppendSwitch(switches::kDisableGpuShaderDiskCache); + parsedCommandLine->AppendSwitch(switches::kDisable2dCanvasAntialiasing); + parsedCommandLine->AppendSwitch(cc::switches::kDisableCompositedAntialiasing); + parsedCommandLine->AppendSwitchASCII(switches::kProfilerTiming, switches::kProfilerTimingDisabledValue); + } GLContextHelper::initialize(); @@ -260,13 +261,13 @@ WebEngineContext::WebEngineContext() contentMainParams.sandbox_info = &sandbox_info; #endif m_contentRunner->Initialize(contentMainParams); - m_browserRunner->Initialize(content::MainFunctionParams(*CommandLine::ForCurrentProcess())); + m_browserRunner->Initialize(content::MainFunctionParams(*base::CommandLine::ForCurrentProcess())); // Once the MessageLoop has been created, attach a top-level RunLoop. m_runLoop.reset(new base::RunLoop); m_runLoop->BeforeRun(); - m_devtools.reset(new DevToolsHttpHandlerDelegateQt); + m_devtools = createDevToolsHttpHandler(); // Force the initialization of MediaCaptureDevicesDispatcher on the UI // thread to avoid a thread check assertion in its constructor when it // first gets referenced on the IO thread. diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h index dea54ef8a..8f034f18f 100644 --- a/src/core/web_engine_context.h +++ b/src/core/web_engine_context.h @@ -41,6 +41,8 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "base/values.h" +#include "components/devtools_http_handler/devtools_http_handler.h" #include <QExplicitlySharedDataPointer> @@ -59,7 +61,6 @@ namespace QtWebEngineCore { class BrowserContextAdapter; class ContentMainDelegateQt; -class DevToolsHttpHandlerDelegateQt; class SurfaceFactoryQt; } // namespace @@ -84,7 +85,7 @@ private: scoped_ptr<content::BrowserMainRunner> m_browserRunner; QObject* m_globalQObject; QExplicitlySharedDataPointer<QtWebEngineCore::BrowserContextAdapter> m_defaultBrowserContext; - scoped_ptr<QtWebEngineCore::DevToolsHttpHandlerDelegateQt> m_devtools; + scoped_ptr<devtools_http_handler::DevToolsHttpHandler> m_devtools; }; #endif // WEB_ENGINE_CONTEXT_H diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp index 980e9a39a..bc030d8f7 100644 --- a/src/core/web_engine_library_info.cpp +++ b/src/core/web_engine_library_info.cpp @@ -162,7 +162,6 @@ QString pluginsPath() if (!initialized) { initialized = true; - const QStringList directories = QCoreApplication::libraryPaths(); Q_FOREACH (const QString &dir, directories) { const QString candidate = dir % "/" % QLatin1String("qtwebengine"); @@ -173,7 +172,6 @@ QString pluginsPath() } if (pluginsPath.isEmpty()) { - qWarning("Qt WebEngine Plugins directory not found. Trying fallback directory... Plugins as for example video codecs MAY NOT work."); pluginsPath = fallbackDir(); } } @@ -276,7 +274,7 @@ base::string16 WebEngineLibraryInfo::getApplicationName() std::string WebEngineLibraryInfo::getApplicationLocale() { - CommandLine *parsedCommandLine = CommandLine::ForCurrentProcess(); + base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess(); if (!parsedCommandLine->HasSwitch(switches::kLang)) return QLocale().bcp47Name().toStdString(); diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp index 74c60b778..b59ec7311 100644 --- a/src/core/web_engine_settings.cpp +++ b/src/core/web_engine_settings.cpp @@ -213,6 +213,8 @@ void WebEngineSettings::initDefaults(bool offTheRecord) m_attributes.insert(HyperlinkAuditingEnabled, false); m_attributes.insert(ScrollAnimatorEnabled, false); m_attributes.insert(ErrorPageEnabled, true); + m_attributes.insert(PluginsEnabled, false); + m_attributes.insert(FullscreenSupportEnabled, false); // Default fonts QFont defaultFont; @@ -277,6 +279,8 @@ void WebEngineSettings::applySettingsToWebPreferences(content::WebPreferences *p prefs->hyperlink_auditing_enabled = testAttribute(HyperlinkAuditingEnabled); prefs->enable_scroll_animator = testAttribute(ScrollAnimatorEnabled); prefs->enable_error_page = testAttribute(ErrorPageEnabled); + prefs->plugins_enabled = testAttribute(PluginsEnabled); + prefs->fullscreen_supported = testAttribute(FullscreenSupportEnabled); // Fonts settings. prefs->standard_font_family_map[content::kCommonScript] = toString16(fontFamily(StandardFont)); diff --git a/src/core/web_engine_settings.h b/src/core/web_engine_settings.h index e9d8010a8..1d8f83184 100644 --- a/src/core/web_engine_settings.h +++ b/src/core/web_engine_settings.h @@ -71,6 +71,8 @@ public: HyperlinkAuditingEnabled, ScrollAnimatorEnabled, ErrorPageEnabled, + PluginsEnabled, + FullscreenSupportEnabled, }; // Must match the values from the public API in qwebenginesettings.h. diff --git a/src/core/yuv_video_node.cpp b/src/core/yuv_video_node.cpp index 23528c8ec..815ea7d51 100644 --- a/src/core/yuv_video_node.cpp +++ b/src/core/yuv_video_node.cpp @@ -61,12 +61,16 @@ protected: "attribute highp vec4 a_position;\n" "attribute mediump vec2 a_texCoord;\n" "uniform highp mat4 matrix;\n" - "varying mediump vec2 v_texCoord;\n" - "uniform mediump vec2 texScale;\n" - "uniform mediump vec2 texOffset;\n" + "varying mediump vec2 v_yaTexCoord;\n" + "varying mediump vec2 v_uvTexCoord;\n" + "uniform mediump vec2 yaTexScale;\n" + "uniform mediump vec2 yaTexOffset;\n" + "uniform mediump vec2 uvTexScale;\n" + "uniform mediump vec2 uvTexOffset;\n" "void main() {\n" " gl_Position = matrix * a_position;\n" - " v_texCoord = a_texCoord * texScale + texOffset;\n" + " v_yaTexCoord = a_texCoord * yaTexScale + yaTexOffset;\n" + " v_uvTexCoord = a_texCoord * uvTexScale + uvTexOffset;\n" "}"; return shader; } @@ -74,19 +78,26 @@ protected: virtual const char *fragmentShader() const Q_DECL_OVERRIDE { // Keep in sync with cc::FragmentShaderYUVVideo static const char *shader = - "varying mediump vec2 v_texCoord;\n" + "varying mediump vec2 v_yaTexCoord;\n" + "varying mediump vec2 v_uvTexCoord;\n" "uniform sampler2D y_texture;\n" "uniform sampler2D u_texture;\n" "uniform sampler2D v_texture;\n" - "uniform lowp float alpha;\n" - "uniform lowp vec3 yuv_adj;\n" - "uniform lowp mat3 yuv_matrix;\n" + "uniform mediump float alpha;\n" + "uniform mediump vec3 yuv_adj;\n" + "uniform mediump mat3 yuv_matrix;\n" + "uniform mediump vec4 ya_clamp_rect;\n" + "uniform mediump vec4 uv_clamp_rect;\n" "void main() {\n" - " lowp float y_raw = texture2D(y_texture, v_texCoord).x;\n" - " lowp float u_unsigned = texture2D(u_texture, v_texCoord).x;\n" - " lowp float v_unsigned = texture2D(v_texture, v_texCoord).x;\n" - " lowp vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;\n" - " lowp vec3 rgb = yuv_matrix * yuv;\n" + " mediump vec2 ya_clamped =\n" + " max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));\n" + " mediump float y_raw = texture2D(y_texture, ya_clamped).x;\n" + " mediump vec2 uv_clamped =\n" + " max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));\n" + " mediump float u_unsigned = texture2D(u_texture, uv_clamped).x;\n" + " mediump float v_unsigned = texture2D(v_texture, uv_clamped).x;\n" + " mediump vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;\n" + " mediump vec3 rgb = yuv_matrix * yuv;\n" " gl_FragColor = vec4(rgb, 1.0) * alpha;\n" "}"; return shader; @@ -94,8 +105,12 @@ protected: virtual void initialize() Q_DECL_OVERRIDE { m_id_matrix = program()->uniformLocation("matrix"); - m_id_texScale = program()->uniformLocation("texScale"); - m_id_texOffset = program()->uniformLocation("texOffset"); + m_id_yaTexScale = program()->uniformLocation("yaTexScale"); + m_id_uvTexScale = program()->uniformLocation("uvTexScale"); + m_id_yaTexOffset = program()->uniformLocation("yaTexOffset"); + m_id_uvTexOffset = program()->uniformLocation("uvTexOffset"); + m_id_yaClampRect = program()->uniformLocation("ya_clamp_rect"); + m_id_uvClampRect = program()->uniformLocation("uv_clamp_rect"); m_id_yTexture = program()->uniformLocation("y_texture"); m_id_uTexture = program()->uniformLocation("u_texture"); m_id_vTexture = program()->uniformLocation("v_texture"); @@ -105,8 +120,12 @@ protected: } int m_id_matrix; - int m_id_texScale; - int m_id_texOffset; + int m_id_yaTexScale; + int m_id_uvTexScale; + int m_id_yaTexOffset; + int m_id_uvTexOffset; + int m_id_yaClampRect; + int m_id_uvClampRect; int m_id_yTexture; int m_id_uTexture; int m_id_vTexture; @@ -123,21 +142,28 @@ protected: virtual const char *fragmentShader() const Q_DECL_OVERRIDE { // Keep in sync with cc::FragmentShaderYUVAVideo static const char *shader = - "varying mediump vec2 v_texCoord;\n" + "varying mediump vec2 v_yaTexCoord;\n" + "varying mediump vec2 v_uvTexCoord;\n" "uniform sampler2D y_texture;\n" "uniform sampler2D u_texture;\n" "uniform sampler2D v_texture;\n" "uniform sampler2D a_texture;\n" - "uniform lowp float alpha;\n" - "uniform lowp vec3 yuv_adj;\n" - "uniform lowp mat3 yuv_matrix;\n" + "uniform mediump float alpha;\n" + "uniform mediump vec3 yuv_adj;\n" + "uniform mediump mat3 yuv_matrix;\n" + "uniform mediump vec4 ya_clamp_rect;\n" + "uniform mediump vec4 uv_clamp_rect;\n" "void main() {\n" - " lowp float y_raw = texture2D(y_texture, v_texCoord).x;\n" - " lowp float u_unsigned = texture2D(u_texture, v_texCoord).x;\n" - " lowp float v_unsigned = texture2D(v_texture, v_texCoord).x;\n" - " lowp float a_raw = texture2D(a_texture, v_texCoord).x;\n" - " lowp vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;\n" - " lowp vec3 rgb = yuv_matrix * yuv;\n" + " mediump vec2 ya_clamped =\n" + " max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));\n" + " mediump float y_raw = texture2D(y_texture, ya_clamped).x;\n" + " mediump vec2 uv_clamped =\n" + " max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));\n" + " mediump float u_unsigned = texture2D(u_texture, uv_clamped).x;\n" + " mediump float v_unsigned = texture2D(v_texture, uv_clamped).x;\n" + " mediump float a_raw = texture2D(a_texture, ya_clamped).x;\n" + " mediump vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;\n" + " mediump vec3 rgb = yuv_matrix * yuv;\n" " gl_FragColor = vec4(rgb, 1.0) * (alpha * a_raw);\n" "}"; return shader; @@ -156,6 +182,8 @@ void YUVVideoMaterialShader::updateState(const RenderState &state, QSGMaterial * { Q_UNUSED(oldMaterial); + // Keep logic in sync with logic in GLRenderer::DrawYUVVideoQuad: + YUVVideoMaterial *mat = static_cast<YUVVideoMaterial *>(newMaterial); program()->setUniformValue(m_id_yTexture, 0); program()->setUniformValue(m_id_uTexture, 1); @@ -170,18 +198,47 @@ void YUVVideoMaterialShader::updateState(const RenderState &state, QSGMaterial * glFuncs.glActiveTexture(GL_TEXTURE0); // Finish with 0 as default texture unit mat->m_yTexture->bind(); - program()->setUniformValue(m_id_texOffset, mat->m_texCoordRect.topLeft()); - program()->setUniformValue(m_id_texScale, mat->m_texCoordRect.size()); + const QSizeF yaSizeScale(1.0f / mat->m_yaTexSize.width(), 1.0f / mat->m_yaTexSize.height()); + const QSizeF uvSizeScale(1.0f / mat->m_uvTexSize.width(), 1.0f / mat->m_uvTexSize.height()); + + const QPointF yaTexOffset(mat->m_yaTexCoordRect.left() * yaSizeScale.width(), mat->m_yaTexCoordRect.top() * yaSizeScale.height()); + const QPointF uvTexOffset(mat->m_uvTexCoordRect.left() * uvSizeScale.width(), mat->m_uvTexCoordRect.top() * uvSizeScale.height()); + const QSizeF yaTexScale(mat->m_yaTexCoordRect.width() * yaSizeScale.width(), mat->m_yaTexCoordRect.height() * yaSizeScale.height()); + const QSizeF uvTexScale(mat->m_uvTexCoordRect.width() * uvSizeScale.width(), mat->m_uvTexCoordRect.height() * uvSizeScale.height()); + program()->setUniformValue(m_id_yaTexOffset, yaTexOffset); + program()->setUniformValue(m_id_uvTexOffset, uvTexOffset); + program()->setUniformValue(m_id_yaTexScale, yaTexScale); + program()->setUniformValue(m_id_uvTexScale, uvTexScale); + QRectF yaClampRect(yaTexOffset, yaTexScale); + QRectF uvClampRect(uvTexOffset, uvTexScale); + yaClampRect = yaClampRect.marginsRemoved(QMarginsF(yaSizeScale.width() * 0.5f, yaSizeScale.height() * 0.5f, + yaSizeScale.width() * 0.5f, yaSizeScale.height() * 0.5f)); + uvClampRect = uvClampRect.marginsRemoved(QMarginsF(uvSizeScale.width() * 0.5f, uvSizeScale.height() * 0.5f, + uvSizeScale.width() * 0.5f, uvSizeScale.height() * 0.5f)); + + const QVector4D yaClampV(yaClampRect.left(), yaClampRect.top(), yaClampRect.right(), yaClampRect.bottom()); + const QVector4D uvClampV(uvClampRect.left(), uvClampRect.top(), uvClampRect.right(), uvClampRect.bottom()); + program()->setUniformValue(m_id_yaClampRect, yaClampV); + program()->setUniformValue(m_id_uvClampRect, uvClampV); // These values are magic numbers that are used in the transformation from YUV // to RGB color values. They are taken from the following webpage: // http://www.fourcc.org/fccyvrgb.php - const float yuv_to_rgb[9] = { + const float yuv_to_rgb_rec601[9] = { 1.164f, 0.0f, 1.596f, 1.164f, -.391f, -.813f, 1.164f, 2.018f, 0.0f, }; - const QMatrix3x3 yuvMatrix(yuv_to_rgb); + const float yuv_to_rgb_rec709[9] = { + 1.164f, 0.0f, 1.793f, + 1.164f, -0.213f, -0.533f, + 1.164f, 2.112f, 0.0f, + }; + const float yuv_to_rgb_jpeg[9] = { + 1.f, 0.0f, 1.402f, + 1.f, -.34414f, -.71414f, + 1.f, 1.772f, 0.0f, + }; // These values map to 16, 128, and 128 respectively, and are computed // as a fraction over 256 (e.g. 16 / 256 = 0.0625). @@ -189,9 +246,35 @@ void YUVVideoMaterialShader::updateState(const RenderState &state, QSGMaterial * // Y - 16 : Gives 16 values of head and footroom for overshooting // U - 128 : Turns unsigned U into signed U [-128,127] // V - 128 : Turns unsigned V into signed V [-128,127] - const QVector3D yuvAdjust(-0.0625f, -0.5f, -0.5f); - program()->setUniformValue(m_id_yuvMatrix, yuvMatrix); - program()->setUniformValue(m_id_yuvAdjust, yuvAdjust); + const float yuv_adjust_constrained[3] = { + -0.0625f, -0.5f, -0.5f, + }; + + // Same as above, but without the head and footroom. + const float yuv_adjust_full[3] = { + 0.0f, -0.5f, -0.5f, + }; + + const float *yuv_to_rgb = 0; + const float *yuv_adjust = 0; + + switch (mat->m_colorSpace) { + case YUVVideoMaterial::REC_601: + yuv_to_rgb = yuv_to_rgb_rec601; + yuv_adjust = yuv_adjust_constrained; + break; + case YUVVideoMaterial::REC_709: + yuv_to_rgb = yuv_to_rgb_rec709; + yuv_adjust = yuv_adjust_constrained; + break; + case YUVVideoMaterial::JPEG: + yuv_to_rgb = yuv_to_rgb_jpeg; + yuv_adjust = yuv_adjust_full; + break; + } + + program()->setUniformValue(m_id_yuvMatrix, QMatrix3x3(yuv_to_rgb)); + program()->setUniformValue(m_id_yuvAdjust, QVector3D(yuv_adjust[0], yuv_adjust[1], yuv_adjust[2])); if (state.isOpacityDirty()) program()->setUniformValue(m_id_opacity, state.opacity()); @@ -217,11 +300,17 @@ void YUVAVideoMaterialShader::updateState(const RenderState &state, QSGMaterial } -YUVVideoMaterial::YUVVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, const QRectF &texCoordRect) +YUVVideoMaterial::YUVVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, + const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize, + YUVVideoMaterial::ColorSpace colorspace) : m_yTexture(yTexture) , m_uTexture(uTexture) , m_vTexture(vTexture) - , m_texCoordRect(texCoordRect) + , m_yaTexCoordRect(yaTexCoordRect) + , m_uvTexCoordRect(uvTexCoordRect) + , m_yaTexSize(yaTexSize) + , m_uvTexSize(uvTexSize) + , m_colorSpace(colorspace) { } @@ -240,8 +329,10 @@ int YUVVideoMaterial::compare(const QSGMaterial *other) const return m_vTexture->textureId() - m->m_vTexture->textureId(); } -YUVAVideoMaterial::YUVAVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture, const QRectF &texCoordRect) - : YUVVideoMaterial(yTexture, uTexture, vTexture, texCoordRect) +YUVAVideoMaterial::YUVAVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture, + const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize, + YUVVideoMaterial::ColorSpace colorspace) + : YUVVideoMaterial(yTexture, uTexture, vTexture, yaTexCoordRect, uvTexCoordRect, yaTexSize, uvTexSize, colorspace) , m_aTexture(aTexture) { setFlag(Blending, aTexture); @@ -260,15 +351,17 @@ int YUVAVideoMaterial::compare(const QSGMaterial *other) const return (m_aTexture ? m_aTexture->textureId() : 0) - (m->m_aTexture ? m->m_aTexture->textureId() : 0); } -YUVVideoNode::YUVVideoNode(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture, const QRectF &texCoordRect) +YUVVideoNode::YUVVideoNode(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture, + const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize, + YUVVideoMaterial::ColorSpace colorspace) : m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4) { setGeometry(&m_geometry); setFlag(QSGNode::OwnsMaterial); if (aTexture) - m_material = new YUVAVideoMaterial(yTexture, uTexture, vTexture, aTexture, texCoordRect); + m_material = new YUVAVideoMaterial(yTexture, uTexture, vTexture, aTexture, yaTexCoordRect, uvTexCoordRect, yaTexSize, uvTexSize, colorspace); else - m_material = new YUVVideoMaterial(yTexture, uTexture, vTexture, texCoordRect); + m_material = new YUVVideoMaterial(yTexture, uTexture, vTexture, yaTexCoordRect, uvTexCoordRect, yaTexSize, uvTexSize, colorspace); setMaterial(m_material); } diff --git a/src/core/yuv_video_node.h b/src/core/yuv_video_node.h index f96df56ce..457c2c7fe 100644 --- a/src/core/yuv_video_node.h +++ b/src/core/yuv_video_node.h @@ -50,7 +50,14 @@ QT_END_NAMESPACE class YUVVideoMaterial : public QSGMaterial { public: - YUVVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, const QRectF &texCoordRect); + enum ColorSpace { + REC_601, // SDTV standard with restricted "studio swing" color range. + REC_709, // HDTV standard with restricted "studio swing" color range. + JPEG // Full color range [0, 255] JPEG color space. + }; + YUVVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, + const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize, + ColorSpace colorspace); virtual QSGMaterialType *type() const Q_DECL_OVERRIDE { static QSGMaterialType theType; @@ -63,13 +70,20 @@ public: QSGTexture *m_yTexture; QSGTexture *m_uTexture; QSGTexture *m_vTexture; - QRectF m_texCoordRect; + QRectF m_yaTexCoordRect; + QRectF m_uvTexCoordRect; + QSizeF m_yaTexSize; + QSizeF m_uvTexSize; + ColorSpace m_colorSpace; + }; class YUVAVideoMaterial : public YUVVideoMaterial { public: - YUVAVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture, const QRectF &texCoordRect); + YUVAVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture, + const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize, + ColorSpace colorspace); virtual QSGMaterialType *type() const Q_DECL_OVERRIDE{ static QSGMaterialType theType; @@ -85,7 +99,9 @@ public: class YUVVideoNode : public QSGGeometryNode { public: - YUVVideoNode(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture, const QRectF &texCoordRect); + YUVVideoNode(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture, + const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize, + YUVVideoMaterial::ColorSpace colorspace); void setRect(const QRectF &rect); private: |