diff options
Diffstat (limited to 'src/core')
81 files changed, 2788 insertions, 939 deletions
diff --git a/src/core/access_token_store_qt.cpp b/src/core/access_token_store_qt.cpp index 5b8fe83f7..1819cd733 100644 --- a/src/core/access_token_store_qt.cpp +++ b/src/core/access_token_store_qt.cpp @@ -56,7 +56,7 @@ namespace QtWebEngineCore { -using content::AccessTokenStore; +using device::AccessTokenStore; using content::BrowserThread; AccessTokenStoreQt::AccessTokenStoreQt() diff --git a/src/core/access_token_store_qt.h b/src/core/access_token_store_qt.h index 973f304c0..ced69a2b6 100644 --- a/src/core/access_token_store_qt.h +++ b/src/core/access_token_store_qt.h @@ -41,7 +41,7 @@ #define ACCESS_TOKEN_STORE_QT_H #include "base/memory/ref_counted.h" -#include "content/public/browser/access_token_store.h" +#include "device/geolocation/access_token_store.h" #include <QtCore/qcompilerdetection.h> #include <QtCore/QFile> @@ -53,7 +53,7 @@ class URLRequestContextGetter; namespace QtWebEngineCore { -class AccessTokenStoreQt : public content::AccessTokenStore { +class AccessTokenStoreQt : public device::AccessTokenStore { public: AccessTokenStoreQt(); ~AccessTokenStoreQt(); diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro index 37f8885bb..cda01db40 100644 --- a/src/core/api/core_api.pro +++ b/src/core/api/core_api.pro @@ -35,6 +35,7 @@ HEADERS = \ qtwebenginecoreglobal_p.h \ qwebenginecookiestore.h \ qwebenginecookiestore_p.h \ + qwebenginehttprequest.h \ qwebengineurlrequestinterceptor.h \ qwebengineurlrequestinfo.h \ qwebengineurlrequestinfo_p.h \ @@ -44,6 +45,7 @@ HEADERS = \ SOURCES = \ qtwebenginecoreglobal.cpp \ qwebenginecookiestore.cpp \ + qwebenginehttprequest.cpp \ qwebengineurlrequestinfo.cpp \ qwebengineurlrequestjob.cpp \ qwebengineurlschemehandler.cpp diff --git a/src/core/api/qwebenginehttprequest.cpp b/src/core/api/qwebenginehttprequest.cpp new file mode 100644 index 000000000..b64af4466 --- /dev/null +++ b/src/core/api/qwebenginehttprequest.cpp @@ -0,0 +1,419 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qplatformdefs.h" +#include <QtCore/qshareddata.h> +#include <QtWebEngineCore/qwebenginehttprequest.h> +#include <algorithm> + +QT_BEGIN_NAMESPACE + +/*! + \class QWebEngineHttpRequest + \since 5.9 + \ingroup webengine + \inmodule QtWebEngineCore + + \brief The QWebEngineHttpRequest class holds a request to be sent with WebEngine. + + QWebEngineHttpRequest represents an HTTP request in the WebEngine networking stack. + It holds the information necessary to send a request over the network. It contains + a URL and some ancillary information that can be used to modify the request. + Both QWebEnginePage::load() and QWebEngineView::load() accept a QWebEngineHttpRequest + as a parameter. +*/ + +/*! + \enum QWebEngineHttpRequest::Method + \brief This enum type describes the method used to send the HTTP request: + + \value Get The GET method. + \value Post The POST method. +*/ + +class QWebEngineHttpRequestPrivate : public QSharedData +{ +public: + QUrl url; + QWebEngineHttpRequest::Method method; + typedef QPair<QByteArray, QByteArray> HeaderPair; + typedef QVector<HeaderPair> Headers; + Headers headers; + QByteArray postData; + + inline QWebEngineHttpRequestPrivate() + { + } + + ~QWebEngineHttpRequestPrivate() + { + } + + QWebEngineHttpRequestPrivate(const QWebEngineHttpRequestPrivate &other) + : QSharedData(other) + { + method = other.method; + url = other.url; + headers = other.headers; + } + + inline bool operator==(const QWebEngineHttpRequestPrivate &other) const + { + return method == other.method + && url == other.url + && headers == other.headers; + } + + Headers::ConstIterator findHeader(const QByteArray &key) const; + Headers allHeaders() const; + QVector<QByteArray> headersKeys() const; + void setHeader(const QByteArray &key, const QByteArray &value); + void unsetHeader(const QByteArray &key); + void setAllHeaders(const Headers &list); + +private: + void setHeaderInternal(const QByteArray &key, const QByteArray &value); +}; + +/*! + Constructs a QWebEngineHttpRequest object with \a url as the URL to be + requested and \a method as the method to be used. + + \sa url(), setUrl() +*/ +QWebEngineHttpRequest::QWebEngineHttpRequest(const QUrl &url, + const QWebEngineHttpRequest::Method &method) + : d(new QWebEngineHttpRequestPrivate) +{ + d->method = method; + d->url = url; +} + +/*! + Creates a copy of \a other. +*/ +QWebEngineHttpRequest::QWebEngineHttpRequest(const QWebEngineHttpRequest &other) + : d(other.d) +{ +} + +/*! + Disposes of the QWebEngineHttpRequest object. +*/ +QWebEngineHttpRequest::~QWebEngineHttpRequest() +{ + // QSharedDataPointer auto deletes + d = 0; +} + +/*! + Returns \c true if this object is the same as \a other (that is, if they + have the same method, URL, and headers). + + \sa operator!=() +*/ +bool QWebEngineHttpRequest::operator==(const QWebEngineHttpRequest &other) const +{ + return d == other.d || *d == *other.d; +} + +/*! + \fn bool QWebEngineHttpRequest::operator!=(const QWebEngineHttpRequest &other) const + + Returns \c false if this object is not the same as \a other. + + \sa operator==() +*/ + +/*! + Creates a copy of \a other. +*/ +QWebEngineHttpRequest &QWebEngineHttpRequest::operator=(const QWebEngineHttpRequest &other) +{ + d = other.d; + return *this; +} + +/*! + \fn void QWebEngineHttpRequest::swap(QWebEngineHttpRequest &other) + + Swaps this WebEngine request with \a other. This function is very + fast and never fails. +*/ + +/*! + Constructs a QWebEngineHttpRequest to \a url that uses the POST method. + + \note \a postData may contain arbitrary strings. They are translated + to appropriate raw data. + + \sa postData, setPostData() +*/ +QWebEngineHttpRequest QWebEngineHttpRequest::postRequest(const QUrl &url, + const QMap<QString, QString> &postData) +{ + QWebEngineHttpRequest result(url); + result.setMethod(QWebEngineHttpRequest::Post); + + QString buffer; + for (QMap<QString, QString>::const_iterator it = postData.begin(); it != postData.end(); it++) { + QByteArray key = QUrl::toPercentEncoding(it.key()); + QByteArray value = QUrl::toPercentEncoding(it.value()); + + if (buffer.length() > 0) + buffer += QLatin1Char('&'); + buffer += key + QLatin1Char('=') + value; + } + result.setPostData(buffer.toLatin1()); + + result.setHeader(QByteArrayLiteral("Content-Type"), + QByteArrayLiteral("application/x-www-form-urlencoded")); + return result; +} + + +/*! + Returns the method this WebEngine request is using. + + \sa setMethod() +*/ +QWebEngineHttpRequest::Method QWebEngineHttpRequest::method() const +{ + return d->method; +} + +/*! + Sets the method this WebEngine request is using to be \a method. + + \sa method() +*/ +void QWebEngineHttpRequest::setMethod(QWebEngineHttpRequest::Method method) +{ + d->method = method; +} + +/*! + Returns the URL this WebEngine request is referring to. + + \sa setUrl() +*/ +QUrl QWebEngineHttpRequest::url() const +{ + return d->url; +} + +/*! + Sets the URL this WebEngine request is referring to be \a url. + + \sa url() +*/ +void QWebEngineHttpRequest::setUrl(const QUrl &url) +{ + d->url = url; +} + +/*! + Returns the (raw) POST data this WebEngine request contains. + + \sa setPostData() +*/ +QByteArray QWebEngineHttpRequest::postData() const +{ + return d->postData; +} + +/*! + Sets the (raw) POST data this WebEngine request contains to be \a postData. + + \sa postData() +*/ +void QWebEngineHttpRequest::setPostData(const QByteArray &postData) +{ + d->postData = postData; +} + +/*! + Returns \c true if the header \a headerName is present in this + WebEngine request. + + \sa setHeader(), header(), unsetHeader(), headers() +*/ +bool QWebEngineHttpRequest::hasHeader(const QByteArray &headerName) const +{ + return d->findHeader(headerName) != d->headers.constEnd(); +} + +/*! + Returns the header specified by \a headerName. If no such header is + present, an empty QByteArray is returned, which may be + indistinguishable from a header that is present but has no content + (use hasHeader() to find out if the header exists or not). + + Headers can be set with setHeader(). + + \sa setHeader(), hasHeader(), unsetHeader(), headers() +*/ +QByteArray QWebEngineHttpRequest::header(const QByteArray &headerName) const +{ + QWebEngineHttpRequestPrivate::Headers::ConstIterator it = + d->findHeader(headerName); + if (it != d->headers.constEnd()) + return it->second; + return QByteArray(); +} + +/*! + Returns a list of all headers that are set in this WebEngine + request. The list is in the order that the headers were set. + + \sa setHeader(), header(), hasHeader(), unsetHeader() +*/ +QVector<QByteArray> QWebEngineHttpRequest::headers() const +{ + return d->headersKeys(); +} + +/*! + Sets the header \a headerName to be of value \a headerValue. + + \note Setting the same header twice overrides the previous + setting. To accomplish the behavior of multiple HTTP headers of + the same name, you should concatenate the two values, separating + them with a comma (",") and set one single header. + + \sa header(), hasHeader(), unsetHeader(), headers() +*/ +void QWebEngineHttpRequest::setHeader(const QByteArray &headerName, const QByteArray &headerValue) +{ + d->setHeader(headerName, headerValue); +} + +/*! + Removes the header specified by \a key, if present. + + \sa setHeader(), header(), hasHeader(), headers() +*/ +void QWebEngineHttpRequest::unsetHeader(const QByteArray &key) +{ + d->setHeader(key, QByteArray()); +} + +QWebEngineHttpRequestPrivate::Headers::ConstIterator +QWebEngineHttpRequestPrivate::findHeader(const QByteArray &key) const +{ + Headers::ConstIterator it = headers.constBegin(); + Headers::ConstIterator end = headers.constEnd(); + for ( ; it != end; ++it) + if (qstricmp(it->first.constData(), key.constData()) == 0) + return it; + + return end; // not found +} + +QWebEngineHttpRequestPrivate::Headers QWebEngineHttpRequestPrivate::allHeaders() const +{ + return headers; +} + +QVector<QByteArray> QWebEngineHttpRequestPrivate::headersKeys() const +{ + QVector<QByteArray> result; + result.reserve(headers.size()); + Headers::ConstIterator it = headers.constBegin(), + end = headers.constEnd(); + for ( ; it != end; ++it) + result << it->first; + + return result; +} + +/*! + \internal + Sets the header specified by \a key to \a value. +*/ +void QWebEngineHttpRequestPrivate::setHeader(const QByteArray &key, const QByteArray &value) +{ + if (key.isEmpty()) + // refuse to accept an empty header + return; + + setHeaderInternal(key, value); +} + +/*! + \internal + Removes the header specified by \a key, if present. +*/ +void QWebEngineHttpRequestPrivate::unsetHeader(const QByteArray &key) +{ + auto firstEqualsKey = [&key](const HeaderPair &header) { + return qstricmp(header.first.constData(), key.constData()) == 0; + }; + headers.erase(std::remove_if(headers.begin(), headers.end(), firstEqualsKey), + headers.end()); +} + +/*! + \internal + Sets the internal headers list to match \a list. +*/ +void QWebEngineHttpRequestPrivate::setAllHeaders(const Headers &list) +{ + headers = list; +} + +/*! + \internal + Sets the header specified by \a key to \a value. + \note key must not be empty. When unsure, use \a setHeader() instead. +*/ +void QWebEngineHttpRequestPrivate::setHeaderInternal(const QByteArray &key, const QByteArray &value) +{ + unsetHeader(key); + + if (value.isNull()) + return; // only wanted to erase key + + HeaderPair pair; + pair.first = key; + pair.second = value; + headers.append(pair); +} + +QT_END_NAMESPACE diff --git a/src/core/api/qwebenginehttprequest.h b/src/core/api/qwebenginehttprequest.h new file mode 100644 index 000000000..5b5948ba1 --- /dev/null +++ b/src/core/api/qwebenginehttprequest.h @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWEBENGINEHTTPREQUEST_H +#define QWEBENGINEHTTPREQUEST_H + +#include <QtWebEngineCore/qtwebenginecoreglobal.h> +#include <QtCore/qshareddata.h> +#include <QtCore/qvector.h> +#include <QtCore/qmap.h> +#include <QtCore/qstring.h> +#include <QtCore/qurl.h> + +QT_BEGIN_NAMESPACE + + +class QWebEngineHttpRequestPrivate; + +class QWEBENGINE_EXPORT QWebEngineHttpRequest +{ +public: + enum Method { + Get, + Post + }; + + explicit QWebEngineHttpRequest(const QUrl &url = QUrl(), + const QWebEngineHttpRequest::Method &method = QWebEngineHttpRequest::Get); + QWebEngineHttpRequest(const QWebEngineHttpRequest &other); + ~QWebEngineHttpRequest(); +#ifdef Q_COMPILER_RVALUE_REFS + QWebEngineHttpRequest &operator=(QWebEngineHttpRequest &&other) Q_DECL_NOTHROW { swap(other); + return *this; } +#endif + QWebEngineHttpRequest &operator=(const QWebEngineHttpRequest &other); + + static QWebEngineHttpRequest postRequest(const QUrl &url, + const QMap<QString, QString> &postData); + void swap(QWebEngineHttpRequest &other) Q_DECL_NOTHROW { qSwap(d, other.d); } + + bool operator==(const QWebEngineHttpRequest &other) const; + inline bool operator!=(const QWebEngineHttpRequest &other) const + { return !operator==(other); } + + Method method() const; + void setMethod(QWebEngineHttpRequest::Method method); + + QUrl url() const; + void setUrl(const QUrl &url); + + QByteArray postData() const; + void setPostData(const QByteArray &postData); + + bool hasHeader(const QByteArray &headerName) const; + QVector<QByteArray> headers() const; + QByteArray header(const QByteArray &headerName) const; + void setHeader(const QByteArray &headerName, const QByteArray &value); + void unsetHeader(const QByteArray &headerName); + +private: + QSharedDataPointer<QWebEngineHttpRequestPrivate> d; + friend class QWebEngineHttpRequestPrivate; +}; + +Q_DECLARE_SHARED(QWebEngineHttpRequest) + +QT_END_NAMESPACE + +#endif diff --git a/src/core/browser_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp index 30e6efc2e..ac4649d3d 100644 --- a/src/core/browser_accessibility_qt.cpp +++ b/src/core/browser_accessibility_qt.cpp @@ -173,9 +173,9 @@ void BrowserAccessibilityQt::setText(QAccessible::Text t, const QString &text) QRect BrowserAccessibilityQt::rect() const { - if (!manager()) // needed implicitly by GetGlobalBoundsRect() + if (!manager()) // needed implicitly by GetScreenBoundsRect() return QRect(); - gfx::Rect bounds = GetGlobalBoundsRect(); + gfx::Rect bounds = GetScreenBoundsRect(); return QRect(bounds.x(), bounds.y(), bounds.width(), bounds.height()); } @@ -573,7 +573,7 @@ void BrowserAccessibilityQt::scrollToSubstring(int startIndex, int endIndex) { int count = characterCount(); if (startIndex < endIndex && endIndex < count) - manager()->ScrollToMakeVisible(*this, GetLocalBoundsForRange(startIndex, endIndex - startIndex)); + manager()->ScrollToMakeVisible(*this, GetPageBoundsForRange(startIndex, endIndex - startIndex)); } QVariant BrowserAccessibilityQt::currentValue() const diff --git a/src/core/browser_context_adapter.cpp b/src/core/browser_context_adapter.cpp index 3396f73ef..863731ff4 100644 --- a/src/core/browser_context_adapter.cpp +++ b/src/core/browser_context_adapter.cpp @@ -101,6 +101,7 @@ BrowserContextAdapter::BrowserContextAdapter(const QString &storageName) BrowserContextAdapter::~BrowserContextAdapter() { + m_browserContext->ShutdownStoragePartitions(); if (m_downloadManagerDelegate) content::BrowserThread::DeleteSoon(content::BrowserThread::UI, FROM_HERE, m_downloadManagerDelegate.take()); BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices(m_browserContext.data()); diff --git a/src/core/browser_context_adapter_client.cpp b/src/core/browser_context_adapter_client.cpp new file mode 100644 index 000000000..3a7447686 --- /dev/null +++ b/src/core/browser_context_adapter_client.cpp @@ -0,0 +1,177 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "browser_context_adapter_client.h" +#include "content/public/browser/download_item.h" +#include "content/public/browser/save_page_type.h" + +#include <QCoreApplication> +#include <QString> + +namespace QtWebEngineCore { + +ASSERT_ENUMS_MATCH(content::DownloadItem::IN_PROGRESS, BrowserContextAdapterClient::DownloadInProgress) +ASSERT_ENUMS_MATCH(content::DownloadItem::COMPLETE, BrowserContextAdapterClient::DownloadCompleted) +ASSERT_ENUMS_MATCH(content::DownloadItem::CANCELLED, BrowserContextAdapterClient::DownloadCancelled) +ASSERT_ENUMS_MATCH(content::DownloadItem::INTERRUPTED, BrowserContextAdapterClient::DownloadInterrupted) + +ASSERT_ENUMS_MATCH(content::SAVE_PAGE_TYPE_UNKNOWN, BrowserContextAdapterClient::UnknownSavePageFormat) +ASSERT_ENUMS_MATCH(content::SAVE_PAGE_TYPE_AS_ONLY_HTML, BrowserContextAdapterClient::SingleHtmlSaveFormat) +ASSERT_ENUMS_MATCH(content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML, BrowserContextAdapterClient::CompleteHtmlSaveFormat) +ASSERT_ENUMS_MATCH(content::SAVE_PAGE_TYPE_AS_MHTML, BrowserContextAdapterClient::MimeHtmlSaveFormat) + +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_NONE, BrowserContextAdapterClient::NoReason) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED, BrowserContextAdapterClient::FileFailed) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED, BrowserContextAdapterClient::FileAccessDenied) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE, BrowserContextAdapterClient::FileNoSpace) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_FILE_NAME_TOO_LONG, BrowserContextAdapterClient::FileNameTooLong) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_FILE_TOO_LARGE, BrowserContextAdapterClient::FileTooLarge) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_FILE_VIRUS_INFECTED, BrowserContextAdapterClient::FileVirusInfected) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR, BrowserContextAdapterClient::FileTransientError) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED, BrowserContextAdapterClient::FileBlocked) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_FILE_SECURITY_CHECK_FAILED, BrowserContextAdapterClient::FileSecurityCheckFailed) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_FILE_TOO_SHORT, BrowserContextAdapterClient::FileTooShort) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_FILE_HASH_MISMATCH, BrowserContextAdapterClient::FileHashMismatch) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED, BrowserContextAdapterClient::NetworkFailed) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_NETWORK_TIMEOUT, BrowserContextAdapterClient::NetworkTimeout) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_NETWORK_DISCONNECTED, BrowserContextAdapterClient::NetworkDisconnected) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_NETWORK_SERVER_DOWN, BrowserContextAdapterClient::NetworkServerDown) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_NETWORK_INVALID_REQUEST, BrowserContextAdapterClient::NetworkInvalidRequest) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED, BrowserContextAdapterClient::ServerFailed) +//ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_SERVER_NO_RANGE, BrowserContextAdapterClient::ServerNoRange) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT, BrowserContextAdapterClient::ServerBadContent) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_SERVER_UNAUTHORIZED, BrowserContextAdapterClient::ServerUnauthorized) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_SERVER_CERT_PROBLEM, BrowserContextAdapterClient::ServerCertProblem) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_SERVER_FORBIDDEN, BrowserContextAdapterClient::ServerForbidden) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_SERVER_UNREACHABLE, BrowserContextAdapterClient::ServerUnreachable) +ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED, BrowserContextAdapterClient::UserCanceled) +//ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_USER_SHUTDOWN, BrowserContextAdapterClient::UserShutdown) +//ASSERT_ENUMS_MATCH(content::DOWNLOAD_INTERRUPT_REASON_CRASH, BrowserContextAdapterClient::Crash) + +QString BrowserContextAdapterClient::downloadInterruptReasonToString(DownloadInterruptReason reason) +{ + switch (reason) { + default: + // Yield an error in debug mode, but fall through to some defined behavior + Q_UNREACHABLE(); + case NoReason: + return QCoreApplication::translate("DownloadInterruptReason", + "Unknown reason or not interrupted"); + case FileFailed: + return QCoreApplication::translate("DownloadInterruptReason", + "General file operation failure"); + case FileAccessDenied: + return QCoreApplication::translate("DownloadInterruptReason", + "The file cannot be written locally, due to access restrictions"); + case FileNoSpace: + return QCoreApplication::translate("DownloadInterruptReason", + "Insufficient space on the target drive"); + case FileNameTooLong: + return QCoreApplication::translate("DownloadInterruptReason", + "The directory or file name is too long"); + case FileTooLarge: + return QCoreApplication::translate("DownloadInterruptReason", + "The file size exceeds the file system limitation"); + case FileVirusInfected: + return QCoreApplication::translate("DownloadInterruptReason", + "The file is infected with a virus"); + case FileTransientError: + return QCoreApplication::translate("DownloadInterruptReason", + "Temporary problem (for example file in use, or too many open files)"); + case FileBlocked: + return QCoreApplication::translate("DownloadInterruptReason", + "The file was blocked due to local policy"); + case FileSecurityCheckFailed: + return QCoreApplication::translate("DownloadInterruptReason", + "Checking the safety of the download failed due to unexpected reasons"); + case FileTooShort: + return QCoreApplication::translate("DownloadInterruptReason", + "File seek past the end of a file (resuming previously interrupted download)"); + case FileHashMismatch: + return QCoreApplication::translate("DownloadInterruptReason", + "The partial file did not match the expected hash"); + case NetworkFailed: + return QCoreApplication::translate("DownloadInterruptReason", + "General network failure"); + case NetworkTimeout: + return QCoreApplication::translate("DownloadInterruptReason", + "The network operation has timed out"); + case NetworkDisconnected: + return QCoreApplication::translate("DownloadInterruptReason", + "The network connection has been terminated"); + case NetworkServerDown: + return QCoreApplication::translate("DownloadInterruptReason", + "The server has gone down"); + case NetworkInvalidRequest: + return QCoreApplication::translate("DownloadInterruptReason", + "The network request was invalid (for example, the URL or scheme is invalid)"); + case ServerFailed: + return QCoreApplication::translate("DownloadInterruptReason", + "General server failure"); + //case ServerNoRange: + // return QCoreApplication::translate("DownloadInterruptReason", + // "Server does not support range requests"); + case ServerBadContent: + return QCoreApplication::translate("DownloadInterruptReason", + "The server does not have the requested data"); + case ServerUnauthorized: + return QCoreApplication::translate("DownloadInterruptReason", + "The server did not authorize access to the resource"); + case ServerCertProblem: + return QCoreApplication::translate("DownloadInterruptReason", + "A problem with the server certificate occurred"); + case ServerForbidden: + return QCoreApplication::translate("DownloadInterruptReason", + "Access forbidden by the server"); + case ServerUnreachable: + return QCoreApplication::translate("DownloadInterruptReason", + "Unexpected server response"); + case UserCanceled: + return QCoreApplication::translate("DownloadInterruptReason", + "Download canceled by the user"); + //case UserShutdown: + // return QCoreApplication::translate("DownloadInterruptReason", + // "The user shut down the browser"); + //case Crash: + // return QCoreApplication::translate("DownloadInterruptReason", + // "The browser crashed"); + } +} + +} // namespace QtWebEngineCore diff --git a/src/core/browser_context_adapter_client.h b/src/core/browser_context_adapter_client.h index faba08591..e1fd02f96 100644 --- a/src/core/browser_context_adapter_client.h +++ b/src/core/browser_context_adapter_client.h @@ -76,6 +76,37 @@ public: SavePage }; + // Keep in sync with content::DownloadInterruptReason + enum DownloadInterruptReason { + NoReason = 0, + FileFailed = 1, + FileAccessDenied = 2, + FileNoSpace = 3, + FileNameTooLong = 5, + FileTooLarge = 6, + FileVirusInfected = 7, + FileTransientError = 10, + FileBlocked = 11, + FileSecurityCheckFailed = 12, + FileTooShort = 13, + FileHashMismatch = 14, + NetworkFailed = 20, + NetworkTimeout = 21, + NetworkDisconnected = 22, + NetworkServerDown = 23, + NetworkInvalidRequest = 24, + ServerFailed = 30, + //ServerNoRange = 31, + ServerBadContent = 33, + ServerUnauthorized = 34, + ServerCertProblem = 35, + ServerForbidden = 36, + ServerUnreachable = 37, + UserCanceled = 40, + //UserShutdown = 41, + //Crash = 50 + }; + struct DownloadItemInfo { const quint32 id; const QUrl url; @@ -88,12 +119,14 @@ public: int savePageFormat; bool accepted; int downloadType; + int downloadInterruptReason; }; virtual ~BrowserContextAdapterClient() { } virtual void downloadRequested(DownloadItemInfo &info) = 0; virtual void downloadUpdated(const DownloadItemInfo &info) = 0; + static QString downloadInterruptReasonToString(DownloadInterruptReason reason); }; } // namespace diff --git a/src/core/browser_context_qt.h b/src/core/browser_context_qt.h index ca65552be..96d3fa861 100644 --- a/src/core/browser_context_qt.h +++ b/src/core/browser_context_qt.h @@ -72,8 +72,6 @@ public: base::FilePath GetCachePath() const; virtual bool IsOffTheRecord() const Q_DECL_OVERRIDE; - net::URLRequestContextGetter *GetRequestContext(); - virtual net::URLRequestContextGetter *CreateMediaRequestContext() Q_DECL_OVERRIDE; virtual net::URLRequestContextGetter *CreateMediaRequestContextForStoragePartition(const base::FilePath& partition_path, bool in_memory) Q_DECL_OVERRIDE; @@ -97,6 +95,7 @@ public: // Profile implementation: PrefService* GetPrefs() override; const PrefService* GetPrefs() const override; + net::URLRequestContextGetter *GetRequestContext() override; BrowserContextAdapter *adapter() { return m_adapter; } diff --git a/src/core/certificate_error_controller.cpp b/src/core/certificate_error_controller.cpp index 18835a5c7..a681de859 100644 --- a/src/core/certificate_error_controller.cpp +++ b/src/core/certificate_error_controller.cpp @@ -71,7 +71,7 @@ ASSERT_ENUMS_MATCH(CertificateErrorController::CertificateErrorEnd, net::ERR_CER void CertificateErrorControllerPrivate::accept(bool accepted) { - callback.Run(accepted); + callback.Run(accepted ? content::CERTIFICATE_REQUEST_RESULT_TYPE_CONTINUE : content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY); } CertificateErrorControllerPrivate::CertificateErrorControllerPrivate(int cert_error, @@ -80,7 +80,7 @@ CertificateErrorControllerPrivate::CertificateErrorControllerPrivate(int cert_er content::ResourceType resource_type, bool _overridable, bool strict_enforcement, - const base::Callback<void(bool)>& cb + const base::Callback<void(content::CertificateRequestResultType)>& cb ) : certError(CertificateErrorController::CertificateError(cert_error)) , requestUrl(toQt(request_url)) diff --git a/src/core/certificate_error_controller_p.h b/src/core/certificate_error_controller_p.h index ee073b64f..abde9a7d5 100644 --- a/src/core/certificate_error_controller_p.h +++ b/src/core/certificate_error_controller_p.h @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE class CertificateErrorControllerPrivate { public: - CertificateErrorControllerPrivate(int cert_error, const net::SSLInfo& ssl_info, const GURL& request_url, content::ResourceType resource_type, bool overridable, bool strict_enforcement, const base::Callback<void(bool)>& callback); + CertificateErrorControllerPrivate(int cert_error, const net::SSLInfo& ssl_info, const GURL& request_url, content::ResourceType resource_type, bool overridable, bool strict_enforcement, const base::Callback<void(content::CertificateRequestResultType)>& callback); void accept(bool accepted); @@ -70,7 +70,7 @@ public: CertificateErrorController::ResourceType resourceType; bool overridable; bool strictEnforcement; - const base::Callback<void(bool)> callback; + const base::Callback<void(content::CertificateRequestResultType)> callback; }; QT_END_NAMESPACE diff --git a/src/core/chromium_gpu_helper.cpp b/src/core/chromium_gpu_helper.cpp index d1133f5c2..1b415b9ec 100644 --- a/src/core/chromium_gpu_helper.cpp +++ b/src/core/chromium_gpu_helper.cpp @@ -75,13 +75,13 @@ gpu::gles2::MailboxManager *mailbox_manager() return gpuChannelManager->mailbox_manager(); } -gpu::gles2::Texture* ConsumeTexture(gpu::gles2::MailboxManager *mailboxManager, unsigned target, const gpu::Mailbox& mailbox) +gpu::gles2::TextureBase* ConsumeTexture(gpu::gles2::MailboxManager *mailboxManager, unsigned target, const gpu::Mailbox& mailbox) { Q_UNUSED(target); return mailboxManager->ConsumeTexture(mailbox); } -unsigned int service_id(gpu::gles2::Texture *tex) +unsigned int service_id(gpu::gles2::TextureBase *tex) { return tex->service_id(); } diff --git a/src/core/chromium_gpu_helper.h b/src/core/chromium_gpu_helper.h index 02fe2d3bb..9954dc1d0 100644 --- a/src/core/chromium_gpu_helper.h +++ b/src/core/chromium_gpu_helper.h @@ -52,7 +52,7 @@ struct Mailbox; class SyncPointManager; namespace gles2 { class MailboxManager; -class Texture; +class TextureBase; } } @@ -65,8 +65,8 @@ base::MessageLoop *gpu_message_loop(); gpu::SyncPointManager *sync_point_manager(); gpu::gles2::MailboxManager *mailbox_manager(); -gpu::gles2::Texture* ConsumeTexture(gpu::gles2::MailboxManager *mailboxManager, unsigned target, const gpu::Mailbox& mailbox); -unsigned int service_id(gpu::gles2::Texture *tex); +gpu::gles2::TextureBase* ConsumeTexture(gpu::gles2::MailboxManager *mailboxManager, unsigned target, const gpu::Mailbox& mailbox); +unsigned int service_id(gpu::gles2::TextureBase *tex); #ifdef Q_OS_QNX typedef void* EGLDisplay; diff --git a/src/core/chromium_overrides.cpp b/src/core/chromium_overrides.cpp index 882f5b1dd..f60b9213b 100644 --- a/src/core/chromium_overrides.cpp +++ b/src/core/chromium_overrides.cpp @@ -65,21 +65,25 @@ #include "ui/gfx/platform_font.h" #endif +#if defined(USE_OPENSSL_CERTS) +#include "net/ssl/openssl_client_key_store.h" +#endif + namespace QtWebEngineCore { -void GetScreenInfoFromNativeWindow(QWindow* window, blink::WebScreenInfo* results) +void GetScreenInfoFromNativeWindow(QWindow* window, content::ScreenInfo* results) { QScreen* screen = window->screen(); - blink::WebScreenInfo r; - r.deviceScaleFactor = screen->devicePixelRatio(); - r.depthPerComponent = 8; + content::ScreenInfo r; + r.device_scale_factor = screen->devicePixelRatio(); + r.depth_per_component = 8; r.depth = screen->depth(); - r.isMonochrome = (r.depth == 1); + r.is_monochrome = (r.depth == 1); QRect screenGeometry = screen->geometry(); - r.rect = blink::WebRect(screenGeometry.x(), screenGeometry.y(), screenGeometry.width(), screenGeometry.height()); + r.rect = gfx::Rect(screenGeometry.x(), screenGeometry.y(), screenGeometry.width(), screenGeometry.height()); QRect available = screen->availableGeometry(); - r.availableRect = blink::WebRect(available.x(), available.y(), available.width(), available.height()); + r.available_rect = gfx::Rect(available.x(), available.y(), available.width(), available.height()); *results = r; } @@ -108,14 +112,15 @@ WebContentsView* CreateWebContentsView(WebContentsImpl *web_contents, } // static -void RenderWidgetHostViewBase::GetDefaultScreenInfo(blink::WebScreenInfo* results) { +void WebContentsView::GetDefaultScreenInfo(content::ScreenInfo* results) +{ QWindow dummy; QtWebEngineCore::GetScreenInfoFromNativeWindow(&dummy, results); } } // namespace content -#if defined(USE_AURA) && !defined(USE_OZONE) +#if defined(USE_AURA) || defined(USE_OZONE) namespace content { // content/common/font_list.h @@ -123,22 +128,25 @@ std::unique_ptr<base::ListValue> GetFontList_SlowBlocking() { std::unique_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); - } + QFontDatabase database; + for (auto family : database.families()){ + std::unique_ptr<base::ListValue> font_item(new base::ListValue()); + font_item->AppendString(family.toStdString()); + font_item->AppendString(family.toStdString()); // localized name. + // TODO(yusukes): Support localized family names. + font_list->Append(std::move(font_item)); + } return std::move(font_list); } #if defined(ENABLE_PLUGINS) // content/browser/renderer_host/pepper/pepper_truetype_font_list.h -void GetFontFamilies_SlowBlocking(std::vector<std::string> *) +void GetFontFamilies_SlowBlocking(std::vector<std::string> *font_families) { - QT_NOT_USED + QFontDatabase database; + for (auto family : database.families()){ + font_families->push_back(family.toStdString()); + } } void GetFontsInFamily_SlowBlocking(const std::string &, std::vector<ppapi::proxy::SerializedTrueTypeFontDesc> *) @@ -149,26 +157,14 @@ void GetFontsInFamily_SlowBlocking(const std::string &, std::vector<ppapi::proxy } // namespace content -namespace ui { - -OSExchangeData::Provider* OSExchangeData::CreateProvider() -{ - QT_NOT_USED - return 0; -} - -} // namespace ui - -#endif // defined(USE_AURA) && !defined(USE_OZONE) +#endif // defined(USE_AURA) || defined(USE_OZONE) #if defined(USE_OPENSSL_CERTS) namespace net { -class SSLPrivateKey { }; -class X509Certificate; -std::unique_ptr<SSLPrivateKey> FetchClientCertPrivateKey(X509Certificate* certificate) +scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey(X509Certificate* certificate) { - return std::unique_ptr<SSLPrivateKey>(); + return OpenSSLClientKeyStore::GetInstance()->FetchClientCertPrivateKey(certificate); } } // namespace net diff --git a/src/core/chromium_overrides.h b/src/core/chromium_overrides.h index b2bd398af..b27bf309c 100644 --- a/src/core/chromium_overrides.h +++ b/src/core/chromium_overrides.h @@ -40,7 +40,7 @@ #ifndef CHROMIUM_OVERRIDES_H #define CHROMIUM_OVERRIDES_H -#include "third_party/WebKit/public/platform/WebScreenInfo.h" +#include "content/public/common/screen_info.h" #include <QtGlobal> QT_BEGIN_NAMESPACE @@ -48,7 +48,7 @@ class QWindow; QT_END_NAMESPACE namespace QtWebEngineCore { -void GetScreenInfoFromNativeWindow(QWindow* window, blink::WebScreenInfo* results); +void GetScreenInfoFromNativeWindow(QWindow* window, content::ScreenInfo* results); } #endif diff --git a/src/core/config/common.pri b/src/core/config/common.pri index b5bb23684..f87eca6e5 100644 --- a/src/core/config/common.pri +++ b/src/core/config/common.pri @@ -1,15 +1,95 @@ # Shared configuration for all our supported platforms -# Trigger Qt-specific build conditions. -GYP_CONFIG += use_qt=1 -# We do not want to ship more external binary blobs, so let v8 embed its startup data. -GYP_CONFIG += v8_use_external_startup_data=0 -# WebSpeech requires Google API keys and adds dependencies on speex and flac. -GYP_CONFIG += enable_web_speech=0 -# We do not use or even include the extensions -GYP_CONFIG += enable_extensions=0 - -sanitize_address: GYP_CONFIG += asan=1 -sanitize_thread: GYP_CONFIG += tsan=1 -sanitize_memory: GYP_CONFIG += msan=1 -sanitize_undefined: GYP_CONFIG += ubsan=1 +use?(gn) { + gn_args += \ + use_qt=true \ + is_component_build=false \ + is_shared=true \ + enable_media_router=false \ + enable_nacl=false \ + enable_remoting=false \ + enable_web_speech=false \ + use_experimental_allocator_shim=false \ + use_allocator=\"none\" \ + v8_use_external_startup_data=false \ + treat_warnings_as_errors=false + + use?(printing) { + gn_args += enable_basic_printing=true enable_print_preview=true + } else { + gn_args += enable_basic_printing=false enable_print_preview=false + } + + use?(pdf) { + gn_args += enable_pdf=true + } else { + gn_args += enable_pdf=false + } + + use?(pepper_plugins) { + gn_args += enable_plugins=true enable_widevine=true + } else { + gn_args += enable_plugins=false enable_widevine=false + } + + use?(spellchecker) { + gn_args += enable_spellcheck=true + } else { + gn_args += enable_spellcheck=false + } + + use?(webrtc) { + gn_args += enable_webrtc=true + } else { + gn_args += enable_webrtc=false + } + + use?(proprietary_codecs): gn_args += proprietary_codecs=true ffmpeg_branding=\"Chrome\" + + CONFIG(release, debug|release) { + force_debug_info: gn_args += symbol_level=1 + else: gn_args += symbol_level=0 + } + + !webcore_debug: gn_args += remove_webcore_debug_symbols=true + !v8base_debug: gn_args += remove_v8base_debug_symbols=true + + # Compiling with -Os makes a huge difference in binary size + contains(WEBENGINE_CONFIG, reduce_binary_size): gn_args += optimize_for_size=true + +} else { + # Trigger Qt-specific build conditions. + GYP_CONFIG += use_qt=1 + # We do not want to ship more external binary blobs, so let v8 embed its startup data. + GYP_CONFIG += v8_use_external_startup_data=0 + # WebSpeech requires Google API keys and adds dependencies on speex and flac. + GYP_CONFIG += enable_web_speech=0 + # We do not use or even include the extensions + GYP_CONFIG += enable_extensions=0 + + sanitize_address: GYP_CONFIG += asan=1 + sanitize_thread: GYP_CONFIG += tsan=1 + sanitize_memory: GYP_CONFIG += msan=1 + sanitize_undefined: GYP_CONFIG += ubsan=1 + + use?(printing) { + GYP_CONFIG += enable_basic_printing=1 enable_print_preview=1 + } else { + GYP_CONFIG += enable_basic_printing=0 enable_print_preview=0 + } + + use?(pdf) { + GYP_CONFIG += enable_pdf=1 + } else { + GYP_CONFIG += enable_pdf=0 + } + + use?(pepper_plugins) { + GYP_CONFIG += enable_plugins=1 enable_widevine=1 + } else { + GYP_CONFIG += enable_plugins=0 enable_widevine=0 + } +} + +use?(webrtc): GYP_CONFIG += enable_webrtc=1 +else: GYP_CONFIG += enable_webrtc=0 diff --git a/src/core/config/desktop_linux.pri b/src/core/config/desktop_linux.pri index 23044619b..e6b11d290 100644 --- a/src/core/config/desktop_linux.pri +++ b/src/core/config/desktop_linux.pri @@ -1,21 +1,32 @@ -GYP_ARGS += "-D qt_os=\"desktop_linux\"" - include(linux.pri) -GYP_CONFIG += \ - desktop_linux=1 \ - enable_widevine=1 \ - enable_basic_printing=1 \ - enable_print_preview=1 \ - enable_pdf=1 +use?(gn) { + gn_args += \ + use_sysroot=false \ + enable_session_service=false \ + enable_notifications=false \ + toolkit_views=false + + use?(icecc) { + gn_args += use_debug_fission=false + } + !use_gold_linker: gn_args += use_gold=false -clang { - GYP_CONFIG += werror= - clang_full_path = $$which($${QMAKE_CXX}) - # Remove the "/bin/clang++" part. - clang_prefix = $$section(clang_full_path, /, 0, -3) - GYP_CONFIG += clang=1 host_clang=1 clang_use_chrome_plugins=0 make_clang_dir=$${clang_prefix} - linux-clang-libc++: GYP_CONFIG += use_system_libcxx=1 } else { - GYP_CONFIG += clang=0 host_clang=0 + + GYP_ARGS += "-D qt_os=\"desktop_linux\"" + + GYP_CONFIG += \ + desktop_linux=1 + + clang { + GYP_CONFIG += werror= + clang_full_path = $$which($${QMAKE_CXX}) + # Remove the "/bin/clang++" part. + clang_prefix = $$section(clang_full_path, /, 0, -3) + GYP_CONFIG += clang=1 host_clang=1 clang_use_chrome_plugins=0 make_clang_dir=$${clang_prefix} + linux-clang-libc++: GYP_CONFIG += use_system_libcxx=1 + } else { + GYP_CONFIG += clang=0 host_clang=0 + } } diff --git a/src/core/config/embedded_linux.pri b/src/core/config/embedded_linux.pri index 7a909f1e2..51d7e2671 100644 --- a/src/core/config/embedded_linux.pri +++ b/src/core/config/embedded_linux.pri @@ -2,6 +2,23 @@ GYP_ARGS += "-D qt_os=\"embedded_linux\" -I config/embedded_linux.gypi" include(linux.pri) +use?(gn) { + gn_args += \ + is_desktop_linux=false \ + use_gold=false \ + use_ozone=true \ + use_sysroot=false \ + enable_session_service=false \ + enable_notifications=false \ + ozone_auto_platforms=false \ + ozone_platform_headless=true \ + toolkit_views=false + + use?(icecc) { + gn_args += use_debug_fission=false + } +} + GYP_CONFIG += \ clang=0 \ desktop_linux=0 \ @@ -9,20 +26,15 @@ GYP_CONFIG += \ embedded=1 \ enable_autofill_dialog=0 \ enable_automation=0 \ - enable_basic_printing=0 \ enable_captive_portal_detection=0 \ enable_extensions=0 \ enable_google_now=0 \ enable_language_detection=0 \ enable_managed_users=0 \ - enable_pdf=0 \ enable_plugin_installation=0 \ - enable_plugins=0 \ - enable_print_preview=0 \ enable_session_service=0 \ enable_task_manager=0 \ enable_themes=0 \ - enable_webrtc=0 \ gtest_target_type=none \ host_clang=0 \ notifications=0 \ @@ -39,6 +51,6 @@ GYP_CONFIG += \ use_x11=0 \ v8_use_snapshot=false \ want_separate_host_toolset=1 \ - angle_enable_gl=0 \ + angle_enable_gl=0 WEBENGINE_CONFIG *= reduce_binary_size diff --git a/src/core/config/embedded_qnx.pri b/src/core/config/embedded_qnx.pri index 3effdb816..f24888776 100644 --- a/src/core/config/embedded_qnx.pri +++ b/src/core/config/embedded_qnx.pri @@ -4,9 +4,6 @@ include(common.pri) GYP_CONFIG += \ disable_nacl=1 \ - enable_basic_printing=0 \ - enable_pdf=0 \ - enable_plugins=0 \ enable_webrtc=0 \ use_ash=0 \ use_aura=1 \ diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri index b91e795ca..232cf2ddd 100644 --- a/src/core/config/linux.pri +++ b/src/core/config/linux.pri @@ -2,6 +2,98 @@ include(common.pri) include($$QTWEBENGINE_OUT_ROOT/qtwebengine-config.pri) QT_FOR_CONFIG += gui-private webengine-private +use?(gn) { + gn_args += \ + use_cups=false \ + use_gconf=false \ + use_gio=false \ + use_gnome_keyring=false \ + use_kerberos=false \ + linux_use_bundled_binutils=false + + use?(nss) { + gn_args += \ + use_nss_certs=true \ + use_openssl_certs=false + } else { + gn_args += \ + use_nss_certs=false \ + use_openssl_certs=true + } + gcc:!clang: greaterThan(QT_GCC_MAJOR_VERSION, 5): gn_args += no_delete_null_pointer_checks=true + + clang { + clang_full_path = $$which($${QMAKE_CXX}) + # Remove the "/bin/clang++" part. + clang_prefix = $$section(clang_full_path, /, 0, -3) + gn_args += \ + is_clang=true \ + clang_use_chrome_plugins=false \ + clang_base_path=\"$${clang_prefix}\" + } else { + gn_args += \ + is_clang=false + } + + cross_compile:!host_build { + TOOLCHAIN_SYSROOT = $$[QT_SYSROOT] + !isEmpty(TOOLCHAIN_SYSROOT): gn_args += target_sysroot=\"$${TOOLCHAIN_SYSROOT}\" + } + + host_build { + gn_args += custom_toolchain=\"$$QTWEBENGINE_OUT_ROOT/src/toolchain:host\" + # Don't bother trying to use system libraries in this case + gn_args += use_glib=false + gn_args += use_system_libffi=false + } else { + gn_args += custom_toolchain=\"$$QTWEBENGINE_OUT_ROOT/src/toolchain:target\" + cross_compile { + gn_args += host_toolchain=\"$$QTWEBENGINE_OUT_ROOT/src/toolchain:host\" + gn_args += v8_snapshot_toolchain=\"$$QTWEBENGINE_OUT_ROOT/src/toolchain:v8_snapshot\" + GN_HOST_CPU = $$gnArch($$QMAKE_HOST.arch) + GN_TARGET_CPU = $$gnArch($$QT_ARCH) + gn_args += host_cpu=\"$$GN_HOST_CPU\" target_cpu=\"$$GN_TARGET_CPU\" + } + !contains(QT_CONFIG, no-pkg-config) { + # Strip '>2 /dev/null' from $$pkgConfigExecutable() + PKGCONFIG = $$first($$list($$pkgConfigExecutable())) + gn_args += pkg_config=\"$$PKGCONFIG\" + } + + qtConfig(system-zlib): use?(system_minizip): gn_args += use_system_zlib=true use_system_minizip=true + qtConfig(system-png): gn_args += use_system_libpng=true + qtConfig(system-jpeg): gn_args += use_system_libjpeg=true + use?(system_harfbuzz): gn_args += use_system_harfbuzz=true + !use?(glib): gn_args += use_glib=false + qtConfig(pulseaudio) { + gn_args += use_pulseaudio=true + } else { + gn_args += use_pulseaudio=false + } + qtConfig(alsa) { + gn_args += use_alsa=true + } else { + gn_args += use_alsa=false + } + packagesExist(libffi): gn_args += use_system_libffi=true + else: gn_args += use_system_libffi=false + !packagesExist(libpci): gn_args += use_libpci=false + !packagesExist(xscrnsaver): gn_args += use_xscrnsaver=false + + use?(system_libevent): gn_args += use_system_libevent=true + use?(system_libwebp): gn_args += use_system_libwebp=true + #use?(system_libsrtp): gn_args += use_system_libsrtp=true + use?(system_libxslt): gn_args += use_system_libxml=true use_system_libxslt=true + #use?(system_jsoncpp): gn_args += use_system_jsoncpp=true + use?(system_opus): gn_args += use_system_opus=true + use?(system_snappy): gn_args += use_system_snappy=true + use?(system_vpx): gn_args += use_system_libvpx=true + use?(system_icu): gn_args += use_system_icu=true icu_use_data_file=false + use?(system_ffmpeg): gn_args += use_system_ffmpeg=true + #use?(system_protobuf): gn_args += use_system_protobuf=true + } +} + # linux_use_bundled_gold currently relies on a hardcoded relative path from chromium/src/out/(Release|Debug) # Disable it along with the -Wl,--threads flag just in case gold isn't installed on the system. GYP_CONFIG += \ diff --git a/src/core/config/mac_osx.pri b/src/core/config/mac_osx.pri index 4111236ed..a9f7207e1 100644 --- a/src/core/config/mac_osx.pri +++ b/src/core/config/mac_osx.pri @@ -19,25 +19,44 @@ QMAKE_CLANG_PATH = $$eval(QMAKE_MAC_SDK.macx-clang.$${QMAKE_MAC_SDK}.QMAKE_CXX) QMAKE_CLANG_PATH = "$${QMAKE_CLANG_DIR}/bin/clang++" message("Using clang++ from $${QMAKE_CLANG_PATH}") system("$${QMAKE_CLANG_PATH} --version") -GYP_CONFIG += \ - qt_os=\"mac\" \ - mac_sdk_min=\"$${QMAKE_MAC_SDK_VERSION}\" \ - mac_deployment_target=\"$${QMAKE_MACOSX_DEPLOYMENT_TARGET}\" \ - make_clang_dir=\"$${QMAKE_CLANG_DIR}\" \ - clang_use_chrome_plugins=0 \ - enable_widevine=1 \ - enable_basic_printing=1 \ - enable_print_preview=1 \ - enable_pdf=1 - -# Force touch API is used in 49-based Chromium, which is included starting with 10.10.3 SDK, so we -# disable the API usage if the SDK version is lower. -!isMinOSXSDKVersion(10, 10, 3): GYP_CONFIG += disable_force_touch=1 - -# Pass a supported -fstack-protect flag depending on Xcode version. -lessThan(QMAKE_XCODE_VERSION, 6.3) { - GYP_CONFIG += use_xcode_stack_protector_strong=0 -} -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}\" + +use?(gn) { + gn_args += \ + is_clang=true \ + use_sysroot=false \ + use_kerberos=false \ + clang_base_path=\"$${QMAKE_CLANG_DIR}\" \ + clang_use_chrome_plugins=false \ + mac_deployment_target=\"$${QMAKE_MACOSX_DEPLOYMENT_TARGET}\" \ + mac_sdk_min=\"$${QMAKE_MAC_SDK_VERSION}\" \ + toolkit_views=false \ + use_external_popup_menu=false + + use?(spellchecker) { + use?(native_spellchecker): gn_args += use_browser_spellchecker=true + else: gn_args += use_browser_spellchecker=false + } else { + macos: gn_args += use_browser_spellchecker=false + } + +} else { + GYP_CONFIG += \ + qt_os=\"mac\" \ + mac_sdk_min=\"$${QMAKE_MAC_SDK_VERSION}\" \ + mac_deployment_target=\"$${QMAKE_MACOSX_DEPLOYMENT_TARGET}\" \ + make_clang_dir=\"$${QMAKE_CLANG_DIR}\" \ + clang_use_chrome_plugins=0 + + # Force touch API is used in 49-based Chromium, which is included starting with 10.10.3 SDK, so we + # disable the API usage if the SDK version is lower. + !isMinOSXSDKVersion(10, 10, 3): GYP_CONFIG += disable_force_touch=1 + + # Pass a supported -fstack-protect flag depending on Xcode version. + lessThan(QMAKE_XCODE_VERSION, 6.3) { + GYP_CONFIG += use_xcode_stack_protector_strong=0 + } + + 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 7f87e885d..405004834 100644 --- a/src/core/config/windows.pri +++ b/src/core/config/windows.pri @@ -2,14 +2,20 @@ GYP_ARGS += "-D qt_os=\"win32\" -I config/windows.gypi" include(common.pri) +gn_args += \ + is_clang=false \ + use_sysroot=false \ + use_kerberos=true \ + enable_notifications=false \ + enable_session_service=false \ + ninja_use_custom_environment_files=false \ + is_multi_dll_chrome=false \ + win_linker_timing=true + GYP_CONFIG += \ disable_nacl=1 \ remoting=0 \ - use_ash=0 \ - enable_widevine=1 \ - enable_basic_printing=1 \ - enable_print_preview=1 \ - enable_pdf=1 + use_ash=0 # Libvpx build needs additional search path on Windows. GYP_ARGS += "-D qtwe_chromium_obj_dir=\"$$OUT_PWD/$$getConfigDir()/obj/$${getChromiumSrcDir()}\"" @@ -20,11 +26,29 @@ GYP_ARGS += "-D perl_exe=\"perl.exe\" -D bison_exe=\"bison.exe\" -D gperf_exe=\" # Gyp's parallel processing is broken on Windows GYP_ARGS += "--no-parallel" + +isDeveloperBuild() { + gn_args += \ + is_win_fastlink=true \ + use_incremental_linking=true +} else { + gn_args += \ + use_incremental_linking=false +} + qtConfig(angle) { + #FIXME: Expect LIBQTANGLE_NAME to be always set + #FIXME: Replace qt_egl_library and qt_glesv2_library into qt_angle_library + LIB_EGL=libEGL + LIB_GLESV2=libGLESv2 + !isEmpty(LIBQTANGLE_NAME) { + LIB_EGL=$$LIBQTANGLE_NAME + LIB_GLESV2=$$LIBQTANGLE_NAME + } CONFIG(release, debug|release) { - GYP_ARGS += "-D qt_egl_library=\"libEGL.lib\" -D qt_glesv2_library=\"libGLESv2.lib\"" + GYP_ARGS += "-D qt_egl_library=\"$${LIB_EGL}.lib\" -D qt_glesv2_library=\"$${LIB_GLESV2}.lib\"" } else { - GYP_ARGS += "-D qt_egl_library=\"libEGLd.lib\" -D qt_glesv2_library=\"libGLESv2d.lib\"" + GYP_ARGS += "-D qt_egl_library=\"$${LIB_EGL}d.lib\" -D qt_glesv2_library=\"$${LIB_GLESV2}d.lib\"" } GYP_ARGS += "-D qt_gl=\"angle\"" } else { @@ -66,7 +90,14 @@ msvc { } GYP_ARGS += "-G msvs_version=$$MSVS_VERSION" + gn_args += visual_studio_version=$$MSVS_VERSION + + SDK_PATH = $$(WINDOWSSDKDIR) + VS_PATH= $$(VSINSTALLDIR) + gn_args += visual_studio_path=$$shell_quote($$VS_PATH) + gn_args += windows_sdk_path=$$shell_quote($$SDK_PATH) + contains(QT_ARCH, "i386"): gn_args += target_cpu=\"x86\" isBuildingOnWin32(): GYP_ARGS += "-D windows_sdk_path=\"C:/Program Files/Windows Kits/10\"" } else { diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp index 787586540..f031da904 100644 --- a/src/core/content_browser_client_qt.cpp +++ b/src/core/content_browser_client_qt.cpp @@ -51,7 +51,6 @@ #include "content/browser/renderer_host/render_view_host_delegate.h" #include "content/public/browser/browser_main_parts.h" #include "content/public/browser/child_process_security_policy.h" -#include "content/public/browser/geolocation_delegate.h" #include "content/public/browser/client_certificate_delegate.h" #include "content/public/browser/media_observer.h" #include "content/public/browser/quota_permission_context.h" @@ -63,6 +62,8 @@ #include "content/public/common/content_switches.h" #include "content/public/common/main_function_params.h" #include "content/public/common/url_constants.h" +#include "device/geolocation/geolocation_delegate.h" +#include "device/geolocation/geolocation_provider.h" #include "ui/base/ui_base_switches.h" #include "ui/display/screen.h" #include "ui/gl/gl_context.h" @@ -80,6 +81,8 @@ #include "dev_tools_http_handler_delegate_qt.h" #ifdef QT_USE_POSITIONING #include "location_provider_qt.h" +#else +#include "device/geolocation/location_provider.h" #endif #include "media_capture_devices_dispatcher.h" #if defined(ENABLE_BASIC_PRINTING) @@ -230,7 +233,29 @@ std::unique_ptr<base::MessagePump> messagePumpFactory() return base::WrapUnique(new MessagePumpForUIQt); } -} // namespace +// A provider of services needed by Geolocation. +class GeolocationDelegateQt : public device::GeolocationDelegate { +public: + GeolocationDelegateQt() {} + scoped_refptr<device::AccessTokenStore> CreateAccessTokenStore() final + { + return scoped_refptr<device::AccessTokenStore>(new AccessTokenStoreQt); + } + + std::unique_ptr<device::LocationProvider> OverrideSystemLocationProvider() final + { +#ifdef QT_USE_POSITIONING + return base::WrapUnique(new LocationProviderQt); +#else + return nullptr; +#endif + } + +private: + DISALLOW_COPY_AND_ASSIGN(GeolocationDelegateQt); +}; + +} // anonymous namespace class BrowserMainPartsQt : public content::BrowserMainParts { @@ -246,6 +271,7 @@ public: void PreMainMessageLoopRun() Q_DECL_OVERRIDE { + device::GeolocationProvider::SetGeolocationDelegate(new GeolocationDelegateQt()); } void PostMainMessageLoopRun() @@ -386,7 +412,7 @@ void ContentBrowserClientQt::RenderProcessWillLaunch(content::RenderProcessHost* // SpellCheckMessageFilter is required for both Hunspell and Native configurations. host->AddFilter(new SpellCheckMessageFilter(id)); #endif -#if defined(Q_OS_MACOS) && defined(USE_BROWSER_SPELLCHECKER) +#if defined(Q_OS_MACOS) && defined(ENABLE_SPELLCHECK) && defined(USE_BROWSER_SPELLCHECKER) host->AddFilter(new SpellCheckMessageFilterPlatform(id)); #endif #if defined(ENABLE_BASIC_PRINTING) @@ -418,49 +444,11 @@ void ContentBrowserClientQt::OverrideWebkitPrefs(content::RenderViewHost *rvh, c static_cast<WebContentsDelegateQt*>(webContents->GetDelegate())->overrideWebPreferences(webContents, web_prefs); } -namespace { - -// A provider of services needed by Geolocation. -class GeolocationDelegateQt : public content::GeolocationDelegate { -public: - GeolocationDelegateQt() {} - content::AccessTokenStore* CreateAccessTokenStore() final - { - return new AccessTokenStoreQt; - } - - content::LocationProvider* OverrideSystemLocationProvider() final - { -#ifdef QT_USE_POSITIONING - if (!m_location_provider) - m_location_provider = base::WrapUnique(new LocationProviderQt); - return m_location_provider.get(); -#else - return nullptr; -#endif - } - -private: -#ifdef QT_USE_POSITIONING - std::unique_ptr<LocationProviderQt> m_location_provider; -#endif - - DISALLOW_COPY_AND_ASSIGN(GeolocationDelegateQt); -}; - -} // anonymous namespace - -content::GeolocationDelegate *ContentBrowserClientQt::CreateGeolocationDelegate() -{ - return new GeolocationDelegateQt; -} - content::QuotaPermissionContext *ContentBrowserClientQt::CreateQuotaPermissionContext() { return new QuotaPermissionContextQt; } - void ContentBrowserClientQt::AllowCertificateError(content::WebContents *webContents, int cert_error, const net::SSLInfo& ssl_info, @@ -469,17 +457,12 @@ void ContentBrowserClientQt::AllowCertificateError(content::WebContents *webCont bool overridable, bool strict_enforcement, bool expired_previous_decision, - const base::Callback<void(bool)>& callback, - content::CertificateRequestResultType* result) + const base::Callback<void(content::CertificateRequestResultType)>& callback) { WebContentsDelegateQt* contentsDelegate = static_cast<WebContentsDelegateQt*>(webContents->GetDelegate()); QSharedPointer<CertificateErrorController> errorController(new CertificateErrorController(new CertificateErrorControllerPrivate(cert_error, ssl_info, request_url, resource_type, overridable, strict_enforcement, callback))); contentsDelegate->allowCertificateError(errorController); - - // If we don't give the user a chance to allow it, we can reject it right away. - if (result && (!overridable || strict_enforcement)) - *result = content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY; } void ContentBrowserClientQt::SelectClientCertificate(content::WebContents * /*webContents*/, diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h index a13d14ff2..b20175439 100644 --- a/src/core/content_browser_client_qt.h +++ b/src/core/content_browser_client_qt.h @@ -87,7 +87,6 @@ public: virtual void ResourceDispatcherHostCreated() Q_DECL_OVERRIDE; virtual gl::GLShareGroup* GetInProcessGpuShareGroup() Q_DECL_OVERRIDE; virtual content::MediaObserver* GetMediaObserver() Q_DECL_OVERRIDE; - virtual content::GeolocationDelegate* CreateGeolocationDelegate() Q_DECL_OVERRIDE; virtual content::QuotaPermissionContext *CreateQuotaPermissionContext() Q_DECL_OVERRIDE; virtual void OverrideWebkitPrefs(content::RenderViewHost *, content::WebPreferences *) Q_DECL_OVERRIDE; virtual void AllowCertificateError(content::WebContents* web_contents, @@ -98,8 +97,7 @@ public: bool overridable, bool strict_enforcement, bool expired_previous_decision, - const base::Callback<void(bool)>& callback, - content::CertificateRequestResultType* result) Q_DECL_OVERRIDE; + const base::Callback<void(content::CertificateRequestResultType)>& callback) Q_DECL_OVERRIDE; virtual void SelectClientCertificate(content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, std::unique_ptr<content::ClientCertificateDelegate> delegate) Q_DECL_OVERRIDE; diff --git a/src/core/content_main_delegate_qt.cpp b/src/core/content_main_delegate_qt.cpp index 84f767ee3..fa55597d1 100644 --- a/src/core/content_main_delegate_qt.cpp +++ b/src/core/content_main_delegate_qt.cpp @@ -48,7 +48,7 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/ui_base_paths.h" #include "ui/base/resource/resource_bundle.h" -#include "grit/net_resources.h" +#include "net/grit/net_resources.h" #include "net/base/net_module.h" #include "content_client_qt.h" diff --git a/src/core/cookie_monster_delegate_qt.cpp b/src/core/cookie_monster_delegate_qt.cpp index 4e52f562a..d2a3377a4 100644 --- a/src/core/cookie_monster_delegate_qt.cpp +++ b/src/core/cookie_monster_delegate_qt.cpp @@ -217,7 +217,7 @@ bool CookieMonsterDelegateQt::canSetCookie(const QUrl &firstPartyUrl, const QByt return true; } -void CookieMonsterDelegateQt::OnCookieChanged(const net::CanonicalCookie& cookie, bool removed, ChangeCause cause) +void CookieMonsterDelegateQt::OnCookieChanged(const net::CanonicalCookie& cookie, bool removed, net::CookieStore::ChangeCause cause) { if (!m_client) return; diff --git a/src/core/cookie_monster_delegate_qt.h b/src/core/cookie_monster_delegate_qt.h index f47dc86df..009abdd68 100644 --- a/src/core/cookie_monster_delegate_qt.h +++ b/src/core/cookie_monster_delegate_qt.h @@ -83,7 +83,7 @@ public: void setClient(QWebEngineCookieStore *client); bool canSetCookie(const QUrl &firstPartyUrl, const QByteArray &cookieLine, const QUrl &url); - void OnCookieChanged(const net::CanonicalCookie& cookie, bool removed, ChangeCause cause) override; + void OnCookieChanged(const net::CanonicalCookie& cookie, bool removed, net::CookieStore::ChangeCause cause) override; private: void GetAllCookiesOnIOThread(const net::CookieMonster::GetCookieListCallback& callback); diff --git a/src/core/core.pro b/src/core/core.pro index a205d39a0..a2f3c3753 100644 --- a/src/core/core.pro +++ b/src/core/core.pro @@ -3,39 +3,73 @@ TEMPLATE = subdirs # core_headers is a dummy module to syncqt the headers so we can # use them by later targets core_headers.file = core_headers.pro - -# core_gyp_generator.pro is a dummy .pro file that is used by qmake -# to generate our main .gyp file -core_gyp_generator.file = core_gyp_generator.pro -core_gyp_generator.depends = core_headers - -# gyp_run.pro calls gyp through gyp_qtwebengine on the qmake step, and ninja on the make step. -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 = core_api -SUBDIRS += core_headers \ - core_gyp_generator +# core_generator.pro is a dummy .pro file that is used by qmake +# to generate our main .gyp/BUILD.gn file +core_generator.file = core_generator.pro +core_generator.depends = core_headers -!win32 { - # gyp_configure_host.pro and gyp_configure_target.pro are phony pro files that - # extract things like compiler and linker from qmake - # Do not use them on Windows, where Qt already expects the toolchain to be - # selected through environment varibles. - gyp_configure_host.file = gyp_configure_host.pro - gyp_configure_target.file = gyp_configure_target.pro - gyp_configure_target.depends = gyp_configure_host +use?(gn) { + # core_gn_generator.pro is a dummy .pro file that is used by qmake + # to generate our main BUILD.gn file - gyp_run.depends += gyp_configure_host gyp_configure_target - SUBDIRS += gyp_configure_host gyp_configure_target -} + core_icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat + core_icu.path = $$[QT_INSTALL_DATA]/resources + core_icu.CONFIG += no_check_exist + + core_locales.files = $$OUT_PWD/$$getConfigDir()/qtwebengine_locales/*.pak + core_locales.path = $$[QT_INSTALL_TRANSLATIONS]/qtwebengine_locales + core_locales.CONFIG += no_check_exist + + core_resources.files = \ + $$OUT_PWD/$$getConfigDir()/qtwebengine_resources.pak \ + $$OUT_PWD/$$getConfigDir()/qtwebengine_resources_100p.pak \ + $$OUT_PWD/$$getConfigDir()/qtwebengine_resources_200p.pak \ + $$OUT_PWD/$$getConfigDir()/qtwebengine_devtools_resources.pak + core_resources.path = $$[QT_INSTALL_DATA]/resources + core_resources.CONFIG += no_check_exist + INSTALLS += core_resources core_locales core_icu + + gn_run.file = gn_run.pro + gn_run.depends = core_generator -SUBDIRS += gyp_run \ - core_api \ - core_module + core_api.depends = gn_run + + SUBDIRS += \ + core_headers \ + core_generator \ + gn_run \ + core_api \ + core_module +} else { + + # gyp_run.pro calls gyp through gyp_qtwebengine on the qmake step, and ninja on the make step. + gyp_run.file = gyp_run.pro + gyp_run.depends = core_generator + core_api.depends = gyp_run + + SUBDIRS += core_headers \ + core_generator + + !win32 { + # gyp_configure_host.pro and gyp_configure_target.pro are phony pro files that + # extract things like compiler and linker from qmake + # Do not use them on Windows, where Qt already expects the toolchain to be + # selected through environment varibles. + gyp_configure_host.file = gyp_configure_host.pro + gyp_configure_target.file = gyp_configure_target.pro + gyp_configure_target.depends = gyp_configure_host + + gyp_run.depends += gyp_configure_host gyp_configure_target + SUBDIRS += gyp_configure_host gyp_configure_target + } + + SUBDIRS += gyp_run \ + core_api \ + core_module +} diff --git a/src/core/core_gyp_generator.pro b/src/core/core_generator.pro index a09683ba6..c99e10ef8 100644 --- a/src/core/core_gyp_generator.pro +++ b/src/core/core_generator.pro @@ -1,10 +1,10 @@ -# This is a dummy .pro file used to extract some aspects of the used configuration and feed them to gyp -# We want the gyp generation step to happen after all the other config steps. For that we need to prepend -# our gyp_generator.prf feature to the CONFIG variable since it is processed backwards -CONFIG = gyp_generator $$CONFIG -GYPFILE = $$OUT_PWD/core_generated.gyp -GYPINCLUDES += $$PWD/qtwebengine.gypi -GYPSRCDIR = $$PWD + +use?(gn) { + include(core_gn_config.pri) + qtConfig(debug_and_release): CONFIG += debug_and_release +} else { + include(core_gyp_config.pri) +} TEMPLATE = lib @@ -13,7 +13,15 @@ include(core_common.pri) macos { # This fixes namespace builds on macOS. Specifically namespace ambiguity issues between Qt and # Chromium forward declarations of NSString. - forward_declaration_macro = $$shell_quote(\"Q_FORWARD_DECLARE_OBJC_CLASS(name)=class name;\") + contains(WEBENGINE_CONFIG, use_gn) { + # The single quotes are present so that qmake iteration does not interpret the space as + # delimiting a new value, they are removed before writing to the GN file, and the final shell + # quoting is done by GN itself. + forward_declaration_macro = "'Q_FORWARD_DECLARE_OBJC_CLASS(name)=class name;'" + } else { + # For GYP, quoting should be done by qmake itself. + forward_declaration_macro = $$shell_quote(\"Q_FORWARD_DECLARE_OBJC_CLASS(name)=class name;\") + } } else { forward_declaration_macro = "Q_FORWARD_DECLARE_OBJC_CLASS=QT_FORWARD_DECLARE_CLASS" } @@ -22,7 +30,8 @@ macos { DEFINES += QT_NO_KEYWORDS \ QT_USE_QSTRINGBUILDER \ $$forward_declaration_macro \ - QTWEBENGINECORE_VERSION_STR=\\\"$$MODULE_VERSION\\\" \ + QTWEBENGINECORE_VERSION_STR=\"$$MODULE_VERSION\" \ + QTWEBENGINEPROCESS_NAME=\"$$QTWEBENGINEPROCESS_NAME\" \ BUILDING_CHROMIUM # Ensure that response files, generated by qtbase/mkspecs/features/moc.prf, are found by moc. @@ -31,7 +40,7 @@ RCC_DIR = $$OUT_PWD/$$getConfigDir()/.rcc # Assume that we want mobile touch and low-end hardware behaviors # whenever we are cross compiling. -cross_compile: DEFINES += QTWEBENGINE_EMBEDDED_SWITCHES +contains(WEBENGINE_CONFIG, embedded_build): DEFINES += QTWEBENGINE_EMBEDDED_SWITCHES qtConfig(egl): CONFIG += egl @@ -45,6 +54,7 @@ SOURCES = \ browser_accessibility_manager_qt.cpp \ browser_accessibility_qt.cpp \ browser_context_adapter.cpp \ + browser_context_adapter_client.cpp \ browser_context_qt.cpp \ browser_message_filter_qt.cpp \ certificate_error_controller.cpp \ @@ -75,7 +85,6 @@ SOURCES = \ native_web_keyboard_event_qt.cpp \ network_delegate_qt.cpp \ ozone_platform_eglfs.cpp \ - pdfium_document_wrapper_qt.cpp \ permission_manager_qt.cpp \ process_main.cpp \ proxy_config_service_qt.cpp \ @@ -83,15 +92,10 @@ SOURCES = \ render_view_observer_host_qt.cpp \ render_widget_host_view_qt.cpp \ renderer/content_renderer_client_qt.cpp \ - renderer/pepper/pepper_flash_renderer_host_qt.cpp \ - renderer/pepper/pepper_renderer_host_factory_qt.cpp \ renderer/render_frame_observer_qt.cpp \ renderer/render_view_observer_qt.cpp \ renderer/user_resource_controller.cpp \ renderer/web_channel_ipc_transport.cpp \ - renderer_host/pepper/pepper_flash_browser_host_qt.cpp \ - renderer_host/pepper/pepper_host_factory_qt.cpp \ - renderer_host/pepper/pepper_isolated_file_system_message_filter.cpp \ renderer_host/resource_dispatcher_host_delegate_qt.cpp \ renderer_host/user_resource_controller_host.cpp \ renderer_host/web_channel_ipc_transport_host.cpp \ @@ -156,7 +160,6 @@ HEADERS = \ media_capture_devices_dispatcher.h \ network_delegate_qt.h \ ozone_platform_eglfs.h \ - pdfium_document_wrapper_qt.h \ permission_manager_qt.h \ process_main.h \ proxy_config_service_qt.h \ @@ -165,15 +168,10 @@ HEADERS = \ render_widget_host_view_qt.h \ render_widget_host_view_qt_delegate.h \ renderer/content_renderer_client_qt.h \ - renderer/pepper/pepper_flash_renderer_host_qt.h \ - renderer/pepper/pepper_renderer_host_factory_qt.h \ renderer/render_frame_observer_qt.h \ renderer/render_view_observer_qt.h \ renderer/user_resource_controller.h \ renderer/web_channel_ipc_transport.h \ - renderer_host/pepper/pepper_flash_browser_host_qt.h \ - renderer_host/pepper/pepper_host_factory_qt.h \ - renderer_host/pepper/pepper_isolated_file_system_message_filter.h \ renderer_host/resource_dispatcher_host_delegate_qt.h \ renderer_host/user_resource_controller_host.h \ renderer_host/web_channel_ipc_transport_host.h \ @@ -198,6 +196,42 @@ HEADERS = \ web_engine_visited_links_manager.h \ web_event_factory.h + +use?(pdf) { + SOURCES += pdfium_document_wrapper_qt.cpp + HEADERS += pdfium_document_wrapper_qt.h +} + +use?(pepper_plugins) { + SOURCES += \ + renderer_host/pepper/pepper_flash_browser_host_qt.cpp \ + renderer_host/pepper/pepper_host_factory_qt.cpp \ + renderer_host/pepper/pepper_isolated_file_system_message_filter.cpp \ + renderer/pepper/pepper_flash_renderer_host_qt.cpp \ + renderer/pepper/pepper_renderer_host_factory_qt.cpp + + HEADERS += \ + renderer_host/pepper/pepper_flash_browser_host_qt.h \ + renderer_host/pepper/pepper_host_factory_qt.h \ + renderer_host/pepper/pepper_isolated_file_system_message_filter.h \ + renderer/pepper/pepper_flash_renderer_host_qt.h \ + renderer/pepper/pepper_renderer_host_factory_qt.h +} + +use?(printing) { + SOURCES += \ + printing_message_filter_qt.cpp \ + print_view_manager_base_qt.cpp \ + print_view_manager_qt.cpp \ + renderer/print_web_view_helper_delegate_qt.cpp + + HEADERS += \ + printing_message_filter_qt.h \ + print_view_manager_base_qt.h \ + print_view_manager_qt.h \ + renderer/print_web_view_helper_delegate_qt.h +} + contains(QT_CONFIG, opengl) { SOURCES += \ yuv_video_node.cpp \ diff --git a/src/core/core_gn_config.pri b/src/core/core_gn_config.pri new file mode 100644 index 000000000..fb671ddb2 --- /dev/null +++ b/src/core/core_gn_config.pri @@ -0,0 +1,10 @@ +CONFIG = gn_generator $$CONFIG +GN_SRC_DIR = $$PWD +GN_FILE = $$OUT_PWD/$$getConfigDir()/BUILD.gn +GN_FIND_MOCABLES_SCRIPT = $$shell_path($$QTWEBENGINE_ROOT/tools/scripts/gn_find_mocables.py) +GN_RUN_BINARY_SCRIPT = $$shell_path($$QTWEBENGINE_ROOT/tools/scripts/gn_run_binary.py) +GN_IMPORTS = $$PWD/qtwebengine.gni +GN_INCLUDES = $$PWD/qtwebengine_sources.gni $$PWD/qtwebengine_resources.gni +GN_CREATE_PRI = true +QMAKE_INTERNAL_INCLUDED_FILES = $$GN_IMPORTS $$GN_INCLUDES $$GN_FILE + diff --git a/src/core/core_gyp_config.pri b/src/core/core_gyp_config.pri new file mode 100644 index 000000000..999d019f9 --- /dev/null +++ b/src/core/core_gyp_config.pri @@ -0,0 +1,5 @@ +CONFIG = gyp_generator $$CONFIG +GYPFILE = $$OUT_PWD/core_generated.gyp +GYPINCLUDES += $$PWD/qtwebengine.gypi +GYPSRCDIR = $$PWD + diff --git a/src/core/core_module.pro b/src/core/core_module.pro index 65e46dcec..fecee2536 100644 --- a/src/core/core_module.pro +++ b/src/core/core_module.pro @@ -4,9 +4,11 @@ include(core_common.pri) # Needed to set a CFBundleIdentifier QMAKE_INFO_PLIST = Info_mac.plist -# Look for linking information produced by gyp for our target according to core_generated.gyp -!include($$OUT_PWD/$$getConfigDir()/$${TARGET}_linking.pri) { - error("Could not find the linking information that gyp should have generated.") +use?(gn): linking_pri = $$OUT_PWD/$$getConfigDir()/$${TARGET}.pri +else: linking_pri = $$OUT_PWD/$$getConfigDir()/$${TARGET}_linking.pri + +!include($$linking_pri) { + error("Could not find the linking information that gyp/gn should have generated.") } load(qt_module) @@ -17,6 +19,32 @@ api_library_path = $$OUT_PWD/api/$$getConfigDir() # Do not precompile any headers. We are only interested in the linker step. PRECOMPILED_HEADER = +use?(gn){ + isEmpty(NINJA_OBJECTS): error("Missing object files from QtWebEngineCore linking pri.") + isEmpty(NINJA_LFLAGS): error("Missing linker flags from QtWebEngineCore linking pri") + isEmpty(NINJA_ARCHIVES): error("Missing archive files from QtWebEngineCore linking pri") + isEmpty(NINJA_LIBS): error("Missing library files from QtWebEngineCore linking pri") + NINJA_OBJECTS = $$eval($$list($$NINJA_OBJECTS)) + # Do manual response file linking for macOS and Linux + + RSP_FILE = $$OUT_PWD/$$getConfigDir()/$${TARGET}.rsp + for(object, NINJA_OBJECTS): RSP_CONTENT += $$object + write_file($$RSP_FILE, RSP_CONTENT) + macos:LIBS_PRIVATE += -Wl,-filelist,$$shell_quote($$RSP_FILE) + linux:LIBS_PRIVATE += @$$RSP_FILE + # QTBUG-58710 add main rsp file on windows + win32:QMAKE_LFLAGS += @$$RSP_FILE + linux: LIBS_PRIVATE += -Wl,--start-group $$NINJA_ARCHIVES -Wl,--end-group + else: LIBS_PRIVATE += $$NINJA_ARCHIVES + LIBS_PRIVATE += $$NINJA_LIB_DIRS $$NINJA_LIBS + # GN's LFLAGS doesn't always work across all the Linux configurations we support. + # The Windows and macOS ones from GN does provide a few useful flags however + linux: QMAKE_LFLAGS += -Wl,--gc-sections -Wl,-O1 -Wl,-z,now -Wl,-z,defs + else: QMAKE_LFLAGS += $$NINJA_LFLAGS + POST_TARGETDEPS += $$NINJA_TARGETDEPS +} + + LIBS_PRIVATE += -L$$api_library_path CONFIG *= no_smart_library_merge osx { @@ -44,7 +72,12 @@ qtConfig(egl): CONFIG += egl linux:qtConfig(separate_debug_info): QMAKE_POST_LINK="cd $(DESTDIR) && $(STRIP) --strip-unneeded $(TARGET)" -REPACK_DIR = $$OUT_PWD/$$getConfigDir()/gen/repack +use?(gn) { + REPACK_DIR = $$OUT_PWD/$$getConfigDir() +} else { + REPACK_DIR = $$OUT_PWD/$$getConfigDir()/gen/repack +} + # Duplicated from resources/resources.gyp LOCALE_LIST = am ar bg bn ca cs da de el en-GB en-US es-419 es et fa fi fil fr gu he hi hr hu id it ja kn ko lt lv ml mr ms nb nl pl pt-BR pt-PT ro ru sk sl sr sv sw ta te th tr uk vi zh-CN zh-TW for(LOC, LOCALE_LIST) { @@ -96,7 +129,7 @@ icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat } } -!win32:!build_pass:debug_and_release { +!build_pass:debug_and_release { # Special GNU make target that ensures linking isn't done for both debug and release builds # at the same time. notParallel.target = .NOTPARALLEL @@ -109,4 +142,6 @@ OTHER_FILES = \ $$files(../3rdparty/chromium/*.mm, true) \ $$files(../3rdparty/chromium/*.py, true) \ $$files(../3rdparty/chromium/*.gyp, true) \ - $$files(../3rdparty/chromium/*.gypi, true) + $$files(../3rdparty/chromium/*.gypi, true) \ + $$files(../3rdparty/chromium/*.gn, true) \ + $$files(../3rdparty/chromium/*.gni, true) diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp index b122a3333..03c76dd19 100644 --- a/src/core/delegated_frame_node.cpp +++ b/src/core/delegated_frame_node.cpp @@ -54,8 +54,9 @@ #include "type_conversion.h" #include "yuv_video_node.h" -#include "base/message_loop/message_loop.h" #include "base/bind.h" +#include "base/message_loop/message_loop.h" +#include "base/threading/thread_task_runner_handle.h" #include "cc/output/delegated_frame_data.h" #include "cc/quads/debug_border_draw_quad.h" #include "cc/quads/draw_quad.h" @@ -65,6 +66,8 @@ #include "cc/quads/texture_draw_quad.h" #include "cc/quads/tile_draw_quad.h" #include "cc/quads/yuv_video_draw_quad.h" +#include "cc/resources/returned_resource.h" +#include "cc/resources/transferable_resource.h" #include "content/common/host_shared_bitmap_manager.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "ui/gl/gl_context.h" @@ -171,6 +174,260 @@ private: QSGGeometry m_geometry; }; +class DelegatedNodeTreeHandler +{ +public: + DelegatedNodeTreeHandler(QVector<QSGNode*> *sceneGraphNodes) + : m_sceneGraphNodes(sceneGraphNodes) + { + } + + virtual ~DelegatedNodeTreeHandler(){} + + virtual void setupRenderPassNode(QSGTexture *, const QRect &, QSGNode *) = 0; + virtual void setupTextureContentNode(QSGTexture *, const QRect &, QSGTexture::Filtering, + QSGTextureNode::TextureCoordinatesTransformMode, + QSGNode *) = 0; + virtual void setupTiledContentNode(QSGTexture *, const QRect &, const QRectF &, + QSGTexture::Filtering, QSGNode *) = 0; + virtual void setupSolidColorNode(const QRect &, const QColor &, QSGNode *) = 0; + virtual void setupDebugBorderNode(QSGGeometry *, QSGFlatColorMaterial *, QSGNode *) = 0; + +#ifndef QT_NO_OPENGL + virtual void setupYUVVideoNode(QSGTexture *, QSGTexture *, QSGTexture *, QSGTexture *, + const QRectF &, const QRectF &, const QSizeF &, const QSizeF &, + YUVVideoMaterial::ColorSpace, float, float, const QRectF &, + QSGNode *) = 0; +#ifdef GL_OES_EGL_image_external + virtual void setupStreamVideoNode(MailboxTexture *, const QRectF &, + const QMatrix4x4 &, QSGNode *) = 0; +#endif // GL_OES_EGL_image_external +#endif // QT_NO_OPENGL +protected: + QVector<QSGNode*> *m_sceneGraphNodes; +}; + +class DelegatedNodeTreeUpdater : public DelegatedNodeTreeHandler +{ +public: + DelegatedNodeTreeUpdater(QVector<QSGNode*> *sceneGraphNodes) + : DelegatedNodeTreeHandler(sceneGraphNodes) + , m_nodeIterator(sceneGraphNodes->begin()) + { + } + + void setupRenderPassNode(QSGTexture *layer, const QRect &rect, QSGNode *) Q_DECL_OVERRIDE + { + QSGInternalImageNode *imageNode = static_cast<QSGInternalImageNode*>(*m_nodeIterator++); + // In case of a missing render pass, set the target rects to be empty and return early. + // cc::GLRenderer::DrawRenderPassQuad silently ignores missing render passes + if (!layer) { + imageNode->setTargetRect(QRect()); + imageNode->setInnerTargetRect(QRect()); + return; + } + imageNode->setTargetRect(rect); + imageNode->setInnerTargetRect(rect); + imageNode->setTexture(layer); + imageNode->update(); + } + + void setupTextureContentNode(QSGTexture *texture, const QRect &rect, + QSGTexture::Filtering filtering, + QSGTextureNode::TextureCoordinatesTransformMode texCoordTransForm, + QSGNode *) Q_DECL_OVERRIDE + { + QSGTextureNode *textureNode = static_cast<QSGTextureNode*>(*m_nodeIterator++); + if (textureNode->texture() != texture) + textureNode->setTexture(texture); + if (textureNode->textureCoordinatesTransform() != texCoordTransForm) + textureNode->setTextureCoordinatesTransform(texCoordTransForm); + if (textureNode->rect() != rect) + textureNode->setRect(rect); + if (textureNode->filtering() != filtering) + textureNode->setFiltering(filtering); + } + void setupTiledContentNode(QSGTexture *texture, const QRect &rect, const QRectF &sourceRect, + QSGTexture::Filtering filtering, QSGNode *) Q_DECL_OVERRIDE + { + QSGTextureNode *textureNode = static_cast<QSGTextureNode*>(*m_nodeIterator++); + + if (textureNode->rect() != rect) + textureNode->setRect(rect); + if (textureNode->sourceRect() != sourceRect) + textureNode->setSourceRect(sourceRect); + if (textureNode->filtering() != filtering) + textureNode->setFiltering(filtering); + if (textureNode->texture() != texture) + textureNode->setTexture(texture); + } + void setupSolidColorNode(const QRect &rect, const QColor &color, QSGNode *) Q_DECL_OVERRIDE + { + QSGRectangleNode *rectangleNode = static_cast<QSGRectangleNode*>(*m_nodeIterator++); + + if (rectangleNode->rect() != rect) + rectangleNode->setRect(rect); + if (rectangleNode->color() != color) + rectangleNode->setColor(color); + } + + void setupDebugBorderNode(QSGGeometry *geometry, QSGFlatColorMaterial *material, + QSGNode *) Q_DECL_OVERRIDE + { + QSGGeometryNode *geometryNode = static_cast<QSGGeometryNode*>(*m_nodeIterator++); + + geometryNode->setGeometry(geometry); + geometryNode->setMaterial(material); + } +#ifndef QT_NO_OPENGL + void setupYUVVideoNode(QSGTexture *, QSGTexture *, QSGTexture *, QSGTexture *, + const QRectF &, const QRectF &, const QSizeF &, const QSizeF &, + YUVVideoMaterial::ColorSpace, float, float, const QRectF &, + QSGNode *) Q_DECL_OVERRIDE + { + Q_UNREACHABLE(); + } +#ifdef GL_OES_EGL_image_external + void setupStreamVideoNode(MailboxTexture *, const QRectF &, + const QMatrix4x4 &, QSGNode *) Q_DECL_OVERRIDE + { + Q_UNREACHABLE(); + } +#endif // GL_OES_EGL_image_external +#endif // QT_NO_OPENGL + +private: + QVector<QSGNode*>::iterator m_nodeIterator; +}; + +class DelegatedNodeTreeCreator : public DelegatedNodeTreeHandler +{ +public: + DelegatedNodeTreeCreator(QVector<QSGNode*> *sceneGraphNodes, + RenderWidgetHostViewQtDelegate *apiDelegate) + : DelegatedNodeTreeHandler(sceneGraphNodes) + , m_apiDelegate(apiDelegate) + { + } + + void setupRenderPassNode(QSGTexture *layer, const QRect &rect, + QSGNode *layerChain) Q_DECL_OVERRIDE + { + // Only QSGInternalImageNode currently supports QSGLayer textures. + QSGInternalImageNode *imageNode = m_apiDelegate->createImageNode(); + layerChain->appendChildNode(imageNode); + m_sceneGraphNodes->append(imageNode); + + // In case of a missing render pass, set the target rects to be empty and return early. + // cc::GLRenderer::DrawRenderPassQuad silently ignores missing render passes + if (!layer) { + imageNode->setTargetRect(QRect()); + imageNode->setInnerTargetRect(QRect()); + return; + } + + imageNode->setTargetRect(rect); + imageNode->setInnerTargetRect(rect); + imageNode->setTexture(layer); + imageNode->update(); + } + + void setupTextureContentNode(QSGTexture *texture, const QRect &rect, + QSGTexture::Filtering filtering, + QSGTextureNode::TextureCoordinatesTransformMode texCoordTransForm, + QSGNode *layerChain) Q_DECL_OVERRIDE + { + QSGTextureNode *textureNode = m_apiDelegate->createTextureNode(); + textureNode->setTextureCoordinatesTransform(texCoordTransForm); + textureNode->setRect(rect); + textureNode->setTexture(texture); + textureNode->setFiltering(filtering); + + layerChain->appendChildNode(textureNode); + m_sceneGraphNodes->append(textureNode); + } + + void setupTiledContentNode(QSGTexture *texture, const QRect &rect, const QRectF &sourceRect, + QSGTexture::Filtering filtering, + QSGNode *layerChain) Q_DECL_OVERRIDE + { + QSGTextureNode *textureNode = m_apiDelegate->createTextureNode(); + textureNode->setRect(rect); + textureNode->setSourceRect(sourceRect); + textureNode->setFiltering(filtering); + textureNode->setTexture(texture); + + layerChain->appendChildNode(textureNode); + m_sceneGraphNodes->append(textureNode); + } + + void setupSolidColorNode(const QRect &rect, const QColor &color, + QSGNode *layerChain) Q_DECL_OVERRIDE + { + QSGRectangleNode *rectangleNode = m_apiDelegate->createRectangleNode(); + rectangleNode->setRect(rect); + rectangleNode->setColor(color); + + layerChain->appendChildNode(rectangleNode); + m_sceneGraphNodes->append(rectangleNode); + } + + void setupDebugBorderNode(QSGGeometry *geometry, QSGFlatColorMaterial *material, + QSGNode *layerChain) Q_DECL_OVERRIDE + { + QSGGeometryNode *geometryNode = new QSGGeometryNode; + geometryNode->setFlags(QSGNode::OwnsGeometry | QSGNode::OwnsMaterial); + + geometryNode->setGeometry(geometry); + geometryNode->setMaterial(material); + + layerChain->appendChildNode(geometryNode); + m_sceneGraphNodes->append(geometryNode); + } + +#ifndef QT_NO_OPENGL + void setupYUVVideoNode(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, + QSGTexture *aTexture, const QRectF &yaTexCoordRect, + const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, + const QSizeF &uvTexSize, YUVVideoMaterial::ColorSpace colorspace, + float rMul, float rOff, const QRectF &rect, + QSGNode *layerChain) Q_DECL_OVERRIDE + { + YUVVideoNode *videoNode = new YUVVideoNode( + yTexture, + uTexture, + vTexture, + aTexture, + yaTexCoordRect, + uvTexCoordRect, + yaTexSize, + uvTexSize, + colorspace, + rMul, + rOff); + videoNode->setRect(rect); + + layerChain->appendChildNode(videoNode); + m_sceneGraphNodes->append(videoNode); + } +#ifdef GL_OES_EGL_image_external + void setupStreamVideoNode(MailboxTexture *texture, const QRectF &rect, + const QMatrix4x4 &textureMatrix, QSGNode *layerChain) Q_DECL_OVERRIDE + { + StreamVideoNode *svideoNode = new StreamVideoNode(texture, false, ExternalTarget); + svideoNode->setRect(rect); + svideoNode->setTextureMatrix(textureMatrix); + layerChain->appendChildNode(svideoNode); + m_sceneGraphNodes->append(svideoNode); + } +#endif // GL_OES_EGL_image_external +#endif // QT_NO_OPENGL + +private: + RenderWidgetHostViewQtDelegate *m_apiDelegate; +}; + + static inline QSharedPointer<QSGLayer> findRenderPassLayer(const cc::RenderPassId &id, const QVector<QPair<cc::RenderPassId, QSharedPointer<QSGLayer> > > &list) { typedef QPair<cc::RenderPassId, QSharedPointer<QSGLayer> > Pair; @@ -368,7 +625,7 @@ void MailboxTexture::setTarget(GLenum target) void MailboxTexture::fetchTexture(gpu::gles2::MailboxManager *mailboxManager) { - gpu::gles2::Texture *tex = ConsumeTexture(mailboxManager, m_target, m_mailboxHolder.mailbox); + gpu::gles2::TextureBase *tex = ConsumeTexture(mailboxManager, m_target, m_mailboxHolder.mailbox); // The texture might already have been deleted (e.g. when navigating away from a page). if (tex) { @@ -513,7 +770,67 @@ static YUVVideoMaterial::ColorSpace toQt(cc::YUVVideoDrawQuad::ColorSpace color_ return YUVVideoMaterial::REC_601; } -void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, cc::ReturnedResourceArray *resourcesToRelease, RenderWidgetHostViewQtDelegate *apiDelegate) +static bool areSharedQuadStatesEqual(const cc::SharedQuadState *layerState, + const cc::SharedQuadState *prevLayerState) +{ + if (layerState->is_clipped != prevLayerState->is_clipped + || layerState->clip_rect != prevLayerState->clip_rect) + return false; + if (layerState->quad_to_target_transform != prevLayerState->quad_to_target_transform) + return false; + return qFuzzyCompare(layerState->opacity, prevLayerState->opacity); +} + +// Compares if the frame data that we got from the Chromium Compositor is +// *structurally* equivalent to the one of the previous frame. +// If it is, we will just reuse and update the old nodes where necessary. +static bool areRenderPassStructuresEqual(cc::DelegatedFrameData *frameData, + cc::DelegatedFrameData *previousFrameData) +{ + if (!previousFrameData) + return false; + + if (previousFrameData->render_pass_list.size() != frameData->render_pass_list.size()) + return false; + + for (unsigned i = 0; i < frameData->render_pass_list.size(); ++i) { + cc::RenderPass *newPass = frameData->render_pass_list.at(i).get(); + cc::RenderPass *prevPass = previousFrameData->render_pass_list.at(i).get(); + + if (newPass->id != prevPass->id) + return false; + + if (newPass->quad_list.size() != prevPass->quad_list.size()) + return false; + + cc::QuadList::ConstBackToFrontIterator it = newPass->quad_list.BackToFrontBegin(); + cc::QuadList::ConstBackToFrontIterator end = newPass->quad_list.BackToFrontEnd(); + cc::QuadList::ConstBackToFrontIterator prevIt = prevPass->quad_list.BackToFrontBegin(); + cc::QuadList::ConstBackToFrontIterator prevEnd = prevPass->quad_list.BackToFrontEnd(); + for (; it != end && prevIt != prevEnd; ++it, ++prevIt) { + const cc::DrawQuad *quad = *it; + const cc::DrawQuad *prevQuad = *prevIt; + if (!areSharedQuadStatesEqual(quad->shared_quad_state, prevQuad->shared_quad_state)) + return false; + if (quad->material != prevQuad->material) + return false; +#ifndef QT_NO_OPENGL + if (quad->material == cc::DrawQuad::YUV_VIDEO_CONTENT) + return false; +#ifdef GL_OES_EGL_image_external + if (quad->material == cc::DrawQuad::STREAM_VIDEO_CONTENT) + return false; +#endif // GL_OES_EGL_image_external +#endif // QT_NO_OPENGL + + } + } + return true; +} + +void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, + cc::ReturnedResourceArray *resourcesToRelease, + RenderWidgetHostViewQtDelegate *apiDelegate) { m_chromiumCompositorData = chromiumCompositorData; cc::DelegatedFrameData* frameData = m_chromiumCompositorData->frameData.get(); @@ -524,13 +841,11 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, // countering the scale of devicePixel-scaled tiles when rendering them // to the final surface. QMatrix4x4 matrix; - matrix.scale(1 / m_chromiumCompositorData->frameDevicePixelRatio, 1 / m_chromiumCompositorData->frameDevicePixelRatio); - setMatrix(matrix); + matrix.scale(1 / m_chromiumCompositorData->frameDevicePixelRatio, + 1 / m_chromiumCompositorData->frameDevicePixelRatio); + if (QSGTransformNode::matrix() != matrix) + setMatrix(matrix); - // Keep the old objects in scope to hold a ref on layers, resources and textures - // that we can re-use. Destroy the remaining objects before returning. - SGObjects previousSGObjects; - qSwap(m_sgObjects, previousSGObjects); QHash<unsigned, QSharedPointer<ResourceHolder> > resourceCandidates; qSwap(m_chromiumCompositorData->resourceHolders, resourceCandidates); @@ -547,14 +862,32 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, } frameData->resource_list.clear(); + QScopedPointer<DelegatedNodeTreeHandler> nodeHandler; - // There is currently no way to know which and how quads changed since the last frame. - // We have to reconstruct the node chain with their geometries on every update. - // Intermediate render pass node chains are going to be destroyed when previousSGObjects - // goes out of scope together with any QSGLayer that could reference them. - while (QSGNode *oldChain = firstChild()) - delete oldChain; + // We first compare if the render passes from the previous frame data are structurally + // equivalent to the render passes in the current frame data. If they are, we are going + // to reuse the old nodes. Otherwise, we will delete the old nodes and build a new tree. + cc::DelegatedFrameData *previousFrameData = m_chromiumCompositorData->previousFrameData.get(); + const bool buildNewTree = !areRenderPassStructuresEqual(frameData, previousFrameData) || m_sceneGraphNodes.empty(); + m_chromiumCompositorData->previousFrameData = nullptr; + SGObjects previousSGObjects; + QVector<QSharedPointer<QSGTexture> > textureStrongRefs; + if (buildNewTree) { + // Keep the old objects in scope to hold a ref on layers, resources and textures + // that we can re-use. Destroy the remaining objects before returning. + qSwap(m_sgObjects, previousSGObjects); + // Discard the scene graph nodes from the previous frame. + while (QSGNode *oldChain = firstChild()) + delete oldChain; + m_sceneGraphNodes.clear(); + nodeHandler.reset(new DelegatedNodeTreeCreator(&m_sceneGraphNodes, apiDelegate)); + } else { + // Save the texture strong refs so they only go out of scope when the method returns and + // the new vector of texture strong refs has been filled. + qSwap(m_sgObjects.textureStrongRefs, textureStrongRefs); + nodeHandler.reset(new DelegatedNodeTreeUpdater(&m_sceneGraphNodes)); + } // The RenderPasses list is actually a tree where a parent RenderPass is connected // to its dependencies through a RenderPassId reference in one or more RenderPassQuads. // The list is already ordered with intermediate RenderPasses placed before their @@ -568,149 +901,165 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, QSGNode *renderPassParent = 0; if (pass != rootRenderPass) { - QSharedPointer<QSGLayer> rpLayer = findRenderPassLayer(pass->id, previousSGObjects.renderPassLayers); - if (!rpLayer) { - rpLayer = QSharedPointer<QSGLayer>(apiDelegate->createLayer()); - // Avoid any premature texture update since we need to wait - // for the GPU thread to produce the dependent resources first. - rpLayer->setLive(false); - } - QSharedPointer<QSGRootNode> rootNode(new QSGRootNode); + QSharedPointer<QSGLayer> rpLayer; + if (buildNewTree) { + rpLayer = findRenderPassLayer(pass->id, previousSGObjects.renderPassLayers); + if (!rpLayer) { + rpLayer = QSharedPointer<QSGLayer>(apiDelegate->createLayer()); + // Avoid any premature texture update since we need to wait + // for the GPU thread to produce the dependent resources first. + rpLayer->setLive(false); + } + QSharedPointer<QSGRootNode> rootNode(new QSGRootNode); + rpLayer->setItem(rootNode.data()); + m_sgObjects.renderPassLayers.append(QPair<cc::RenderPassId, + QSharedPointer<QSGLayer> >(pass->id, rpLayer)); + m_sgObjects.renderPassRootNodes.append(rootNode); + renderPassParent = rootNode.data(); + } else + rpLayer = findRenderPassLayer(pass->id, m_sgObjects.renderPassLayers); + rpLayer->setRect(toQt(pass->output_rect)); rpLayer->setSize(toQt(pass->output_rect.size())); rpLayer->setFormat(pass->has_transparent_background ? GL_RGBA : GL_RGB); - rpLayer->setItem(rootNode.data()); - m_sgObjects.renderPassLayers.append(QPair<cc::RenderPassId, QSharedPointer<QSGLayer> >(pass->id, rpLayer)); - m_sgObjects.renderPassRootNodes.append(rootNode); - renderPassParent = rootNode.data(); } else renderPassParent = this; - QSGNode *renderPassChain = buildRenderPassChain(renderPassParent); - const cc::SharedQuadState *currentLayerState = 0; - QSGNode *currentLayerChain = 0; + const cc::SharedQuadState *currentLayerState = nullptr; + QSGNode *currentLayerChain = nullptr; + + QSGNode *renderPassChain = nullptr; + if (buildNewTree) + renderPassChain = buildRenderPassChain(renderPassParent); cc::QuadList::ConstBackToFrontIterator it = pass->quad_list.BackToFrontBegin(); cc::QuadList::ConstBackToFrontIterator end = pass->quad_list.BackToFrontEnd(); for (; it != end; ++it) { const cc::DrawQuad *quad = *it; - if (currentLayerState != quad->shared_quad_state) { + if (buildNewTree && currentLayerState != quad->shared_quad_state) { currentLayerState = quad->shared_quad_state; currentLayerChain = buildLayerChain(renderPassChain, currentLayerState); } switch (quad->material) { case cc::DrawQuad::RENDER_PASS: { - const cc::RenderPassDrawQuad *renderPassQuad = cc::RenderPassDrawQuad::MaterialCast(quad); - QSGTexture *layer = findRenderPassLayer(renderPassQuad->render_pass_id, m_sgObjects.renderPassLayers).data(); - // cc::GLRenderer::DrawRenderPassQuad silently ignores missing render passes. - if (!layer) - continue; + const cc::RenderPassDrawQuad *renderPassQuad + = cc::RenderPassDrawQuad::MaterialCast(quad); + QSGTexture *layer = findRenderPassLayer(renderPassQuad->render_pass_id, + m_sgObjects.renderPassLayers).data(); - // Only QSGInternalImageNode currently supports QSGLayer textures. - QSGInternalImageNode *imageNode = apiDelegate->createImageNode(); - imageNode->setTargetRect(toQt(quad->rect)); - imageNode->setInnerTargetRect(toQt(quad->rect)); - imageNode->setTexture(layer); - imageNode->update(); - currentLayerChain->appendChildNode(imageNode); + nodeHandler->setupRenderPassNode(layer, toQt(quad->rect), currentLayerChain); break; } case cc::DrawQuad::TEXTURE_CONTENT: { const cc::TextureDrawQuad *tquad = cc::TextureDrawQuad::MaterialCast(quad); - ResourceHolder *resource = findAndHoldResource(tquad->resource_id(), resourceCandidates); - - QSGTextureNode *textureNode = apiDelegate->createTextureNode(); - textureNode->setTextureCoordinatesTransform(tquad->y_flipped ? QSGTextureNode::MirrorVertically : QSGTextureNode::NoTransform); - textureNode->setRect(toQt(quad->rect)); - textureNode->setFiltering(resource->transferableResource().filter == GL_LINEAR ? QSGTexture::Linear : QSGTexture::Nearest); - textureNode->setTexture(initAndHoldTexture(resource, quad->ShouldDrawWithBlending(), apiDelegate)); - currentLayerChain->appendChildNode(textureNode); + ResourceHolder *resource = findAndHoldResource(tquad->resource_id(), + resourceCandidates); + + nodeHandler->setupTextureContentNode( + initAndHoldTexture(resource, + quad->ShouldDrawWithBlending(), + apiDelegate), + toQt(quad->rect), + resource->transferableResource().filter == GL_LINEAR + ? QSGTexture::Linear + : QSGTexture::Nearest, + tquad->y_flipped ? QSGTextureNode::MirrorVertically + : QSGTextureNode::NoTransform, + currentLayerChain); break; } case cc::DrawQuad::SOLID_COLOR: { const cc::SolidColorDrawQuad *scquad = cc::SolidColorDrawQuad::MaterialCast(quad); - QSGRectangleNode *rectangleNode = apiDelegate->createRectangleNode(); - // Qt only supports MSAA and this flag shouldn't be needed. // If we ever want to use QSGRectangleNode::setAntialiasing for this we should // try to see if we can do something similar for tile quads first. Q_UNUSED(scquad->force_anti_aliasing_off); - - rectangleNode->setRect(toQt(quad->rect)); - rectangleNode->setColor(toQt(scquad->color)); - currentLayerChain->appendChildNode(rectangleNode); + nodeHandler->setupSolidColorNode(toQt(quad->rect), toQt(scquad->color), + currentLayerChain); break; #ifndef QT_NO_OPENGL } case cc::DrawQuad::DEBUG_BORDER: { - const cc::DebugBorderDrawQuad *dbquad = cc::DebugBorderDrawQuad::MaterialCast(quad); - QSGGeometryNode *geometryNode = new QSGGeometryNode; + const cc::DebugBorderDrawQuad *dbquad + = cc::DebugBorderDrawQuad::MaterialCast(quad); - QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4); + QSGGeometry *geometry + = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4); geometry->setDrawingMode(GL_LINE_LOOP); geometry->setLineWidth(dbquad->width); - // QSGGeometry::updateRectGeometry would actually set the corners in the following order: - // top-left, bottom-left, top-right, bottom-right, leading to a nice criss cross, instead - // of having a closed loop. + // QSGGeometry::updateRectGeometry would actually set the + // corners in the following order: + // top-left, bottom-left, top-right, bottom-right, leading to a nice criss cross, + // instead of having a closed loop. const gfx::Rect &r(dbquad->rect); geometry->vertexDataAsPoint2D()[0].set(r.x(), r.y()); geometry->vertexDataAsPoint2D()[1].set(r.x() + r.width(), r.y()); geometry->vertexDataAsPoint2D()[2].set(r.x() + r.width(), r.y() + r.height()); geometry->vertexDataAsPoint2D()[3].set(r.x(), r.y() + r.height()); - geometryNode->setGeometry(geometry); QSGFlatColorMaterial *material = new QSGFlatColorMaterial; material->setColor(toQt(dbquad->color)); - geometryNode->setMaterial(material); - geometryNode->setFlags(QSGNode::OwnsGeometry | QSGNode::OwnsMaterial); - currentLayerChain->appendChildNode(geometryNode); + nodeHandler->setupDebugBorderNode(geometry, material, currentLayerChain); break; #endif } case cc::DrawQuad::TILED_CONTENT: { const cc::TileDrawQuad *tquad = cc::TileDrawQuad::MaterialCast(quad); - ResourceHolder *resource = findAndHoldResource(tquad->resource_id(), resourceCandidates); - - QSGTextureNode *textureNode = apiDelegate->createTextureNode(); - textureNode->setRect(toQt(quad->rect)); - textureNode->setSourceRect(toQt(tquad->tex_coord_rect)); - textureNode->setFiltering(resource->transferableResource().filter == GL_LINEAR ? QSGTexture::Linear : QSGTexture::Nearest); - textureNode->setTexture(initAndHoldTexture(resource, quad->ShouldDrawWithBlending(), apiDelegate)); - currentLayerChain->appendChildNode(textureNode); + ResourceHolder *resource + = findAndHoldResource(tquad->resource_id(), resourceCandidates); + nodeHandler->setupTiledContentNode( + initAndHoldTexture(resource, + quad->ShouldDrawWithBlending(), + apiDelegate), + toQt(quad->rect), toQt(tquad->tex_coord_rect), + resource->transferableResource().filter + == GL_LINEAR ? QSGTexture::Linear + : QSGTexture::Nearest, + currentLayerChain); break; #ifndef QT_NO_OPENGL } case cc::DrawQuad::YUV_VIDEO_CONTENT: { const cc::YUVVideoDrawQuad *vquad = cc::YUVVideoDrawQuad::MaterialCast(quad); - ResourceHolder *yResource = findAndHoldResource(vquad->y_plane_resource_id(), resourceCandidates); - ResourceHolder *uResource = findAndHoldResource(vquad->u_plane_resource_id(), resourceCandidates); - ResourceHolder *vResource = findAndHoldResource(vquad->v_plane_resource_id(), resourceCandidates); + ResourceHolder *yResource + = findAndHoldResource(vquad->y_plane_resource_id(), resourceCandidates); + ResourceHolder *uResource + = findAndHoldResource(vquad->u_plane_resource_id(), resourceCandidates); + ResourceHolder *vResource + = findAndHoldResource(vquad->v_plane_resource_id(), resourceCandidates); ResourceHolder *aResource = 0; - // This currently requires --enable-vp8-alpha-playback and needs a video with alpha data to be triggered. + // This currently requires --enable-vp8-alpha-playback and + // needs a video with alpha data to be triggered. if (vquad->a_plane_resource_id()) - aResource = findAndHoldResource(vquad->a_plane_resource_id(), resourceCandidates); - - YUVVideoNode *videoNode = new YUVVideoNode( - initAndHoldTexture(yResource, quad->ShouldDrawWithBlending()), - initAndHoldTexture(uResource, quad->ShouldDrawWithBlending()), - initAndHoldTexture(vResource, quad->ShouldDrawWithBlending()), - 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), - vquad->resource_multiplier, vquad->resource_offset); - videoNode->setRect(toQt(quad->rect)); - currentLayerChain->appendChildNode(videoNode); + aResource = findAndHoldResource(vquad->a_plane_resource_id(), + resourceCandidates); + + nodeHandler->setupYUVVideoNode( + initAndHoldTexture(yResource, quad->ShouldDrawWithBlending()), + initAndHoldTexture(uResource, quad->ShouldDrawWithBlending()), + initAndHoldTexture(vResource, quad->ShouldDrawWithBlending()), + 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), + vquad->resource_multiplier, vquad->resource_offset, + toQt(quad->rect), + currentLayerChain); break; #ifdef GL_OES_EGL_image_external } case cc::DrawQuad::STREAM_VIDEO_CONTENT: { const cc::StreamVideoDrawQuad *squad = cc::StreamVideoDrawQuad::MaterialCast(quad); - ResourceHolder *resource = findAndHoldResource(squad->resource_id(), resourceCandidates); - MailboxTexture *texture = static_cast<MailboxTexture *>(initAndHoldTexture(resource, quad->ShouldDrawWithBlending())); - texture->setTarget(GL_TEXTURE_EXTERNAL_OES); // since this is not default TEXTURE_2D type - - StreamVideoNode *svideoNode = new StreamVideoNode(texture, false, ExternalTarget); - svideoNode->setRect(toQt(squad->rect)); - svideoNode->setTextureMatrix(toQt(squad->matrix.matrix())); - currentLayerChain->appendChildNode(svideoNode); + ResourceHolder *resource = findAndHoldResource(squad->resource_id(), + resourceCandidates); + MailboxTexture *texture + = static_cast<MailboxTexture *>( + initAndHoldTexture(resource, quad->ShouldDrawWithBlending()) + ); + // since this is not default TEXTURE_2D type + texture->setTarget(GL_TEXTURE_EXTERNAL_OES); + + nodeHandler->setupStreamVideoNode(texture, toQt(squad->rect), + toQt(squad->matrix.matrix()), currentLayerChain); break; #endif // GL_OES_EGL_image_external #endif // QT_NO_OPENGL @@ -721,9 +1070,11 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, } } } + // Send resources of remaining candidates back to the child compositors so that + // they can be freed or reused. + typedef QHash<unsigned, QSharedPointer<ResourceHolder> >::const_iterator + ResourceHolderIterator; - // Send resources of remaining candidates back to the child compositors so that they can be freed or reused. - typedef QHash<unsigned, QSharedPointer<ResourceHolder> >::const_iterator ResourceHolderIterator; ResourceHolderIterator end = resourceCandidates.constEnd(); for (ResourceHolderIterator it = resourceCandidates.constBegin(); it != end ; ++it) resourcesToRelease->push_back((*it)->returnResource()); @@ -777,7 +1128,7 @@ void DelegatedFrameNode::fetchAndSyncMailboxes(QList<MailboxTexture *> &mailboxe continue; } } - gpuMessageLoop->PostTask(FROM_HERE, base::Bind(&DelegatedFrameNode::pullTexture, this, mailboxTexture)); + gpuMessageLoop->task_runner()->PostTask(FROM_HERE, base::Bind(&DelegatedFrameNode::pullTexture, this, mailboxTexture)); } m_mailboxesFetchedWaitCond.wait(&m_mutex); @@ -869,7 +1220,7 @@ void DelegatedFrameNode::pullTexture(DelegatedFrameNode *frameNode, MailboxTextu delete fence; } if (--frameNode->m_numPendingSyncPoints == 0) - base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&DelegatedFrameNode::fenceAndUnlockQt, frameNode)); + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(&DelegatedFrameNode::fenceAndUnlockQt, frameNode)); #else Q_UNUSED(frameNode) Q_UNUSED(texture) diff --git a/src/core/delegated_frame_node.h b/src/core/delegated_frame_node.h index 36ec20f1d..6178bd232 100644 --- a/src/core/delegated_frame_node.h +++ b/src/core/delegated_frame_node.h @@ -74,6 +74,7 @@ public: ChromiumCompositorData() : frameDevicePixelRatio(1) { } QHash<unsigned, QSharedPointer<ResourceHolder> > resourceHolders; std::unique_ptr<cc::DelegatedFrameData> frameData; + std::unique_ptr<cc::DelegatedFrameData> previousFrameData; qreal frameDevicePixelRatio; }; @@ -100,6 +101,7 @@ private: QVector<QSharedPointer<QSGRootNode> > renderPassRootNodes; QVector<QSharedPointer<QSGTexture> > textureStrongRefs; } m_sgObjects; + QVector<QSGNode*> m_sceneGraphNodes; int m_numPendingSyncPoints; QWaitCondition m_mailboxesFetchedWaitCond; QMutex m_mutex; diff --git a/src/core/dev_tools_http_handler_delegate_qt.cpp b/src/core/dev_tools_http_handler_delegate_qt.cpp index 5fd35ee29..468c5f05f 100644 --- a/src/core/dev_tools_http_handler_delegate_qt.cpp +++ b/src/core/dev_tools_http_handler_delegate_qt.cpp @@ -53,11 +53,10 @@ #include "base/memory/ptr_util.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/browser/devtools/devtools_http_handler.h" #include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/devtools_frontend_host.h" +#include "content/public/browser/devtools_socket_factory.h" #include "content/public/browser/favicon_status.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/render_view_host.h" @@ -69,30 +68,26 @@ #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"; - -class TCPServerSocketFactory - : public DevToolsHttpHandler::ServerSocketFactory { +class TCPServerSocketFactory : public content::DevToolsSocketFactory { public: TCPServerSocketFactory(const std::string& address, int port, int backlog) : m_address(address), m_port(port), m_backlog(backlog) {} private: std::unique_ptr<net::ServerSocket> CreateForHttpServer() override { - std::unique_ptr<net::ServerSocket> socket(new net::TCPServerSocket(nullptr, net::NetLog::Source())); + std::unique_ptr<net::ServerSocket> socket(new net::TCPServerSocket(nullptr, net::NetLogSource())); if (socket->ListenWithAddressAndPort(m_address, m_port, m_backlog) != net::OK) return std::unique_ptr<net::ServerSocket>(); return socket; } + std::unique_ptr<net::ServerSocket> CreateForTethering(std::string* out_name) override + { + return nullptr; + } const std::string m_address; int m_port; @@ -100,103 +95,23 @@ private: DISALLOW_COPY_AND_ASSIGN(TCPServerSocketFactory); }; -class DevToolsDiscoveryProviderQt : public DevToolsDiscoveryManager::Provider { -public: - DevToolsTargetDescriptor::List GetDescriptors() override; -}; - -class Target : public DevToolsTargetDescriptor { -public: - explicit Target(scoped_refptr<DevToolsAgentHost> agent_host); - - virtual std::string GetId() const override { return agent_host_->GetId(); } - virtual std::string GetParentId() const override { return std::string(); } - virtual std::string GetType() const override { - 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: - break; - } - return kTargetTypeOther; - } - virtual std::string GetTitle() const override { return agent_host_->GetTitle(); } - virtual std::string GetDescription() const override { return std::string(); } - virtual GURL GetURL() const override { return agent_host_->GetURL(); } - virtual GURL GetFaviconURL() const override { return favicon_url_; } - virtual base::TimeTicks GetLastActivityTime() const override { - return last_activity_time_; - } - virtual bool IsAttached() const override { - return agent_host_->IsAttached(); - } - virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() const override { - return agent_host_; - } - virtual bool Activate() const override; - virtual bool Close() const override; - -private: - scoped_refptr<DevToolsAgentHost> agent_host_; - GURL favicon_url_; - base::TimeTicks last_activity_time_; -}; - -Target::Target(scoped_refptr<DevToolsAgentHost> agent_host) - : agent_host_(agent_host) -{ - if (WebContents* web_contents = agent_host_->GetWebContents()) { - NavigationController& controller = web_contents->GetController(); - NavigationEntry* entry = controller.GetActiveEntry(); - if (entry != NULL && entry->GetURL().is_valid()) - favicon_url_ = entry->GetFavicon().url; - last_activity_time_ = web_contents->GetLastActiveTime(); - } -} - -bool Target::Activate() const { - return agent_host_->Activate(); -} - -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 { -std::unique_ptr<DevToolsHttpHandler> createDevToolsHttpHandler() -{ - DevToolsHttpHandlerDelegateQt *delegate = new DevToolsHttpHandlerDelegateQt(); - if (!delegate->isValid()) { - delete delegate; - return nullptr; - } - std::unique_ptr<DevToolsHttpHandler::ServerSocketFactory> factory(new TCPServerSocketFactory(delegate->bindAddress().toStdString(), delegate->port(), 1)); - // Ownership of the delegate is taken over the devtools http handler. - std::unique_ptr<DevToolsHttpHandler> handler(new DevToolsHttpHandler(std::move(factory), std::string(), delegate, base::FilePath(), base::FilePath(), std::string(), std::string())); - DevToolsDiscoveryManager::GetInstance()->AddProvider(base::WrapUnique(new DevToolsDiscoveryProviderQt())); - return std::move(handler); -} - -DevToolsHttpHandlerDelegateQt::DevToolsHttpHandlerDelegateQt() +DevToolsServerQt::DevToolsServerQt() : m_bindAddress(QLatin1String("127.0.0.1")) , m_port(0) , m_valid(false) + , m_isStarted(false) +{ } + +DevToolsServerQt::~DevToolsServerQt() +{ + stop(); +} + +void DevToolsServerQt::parseAddressAndPort() { const QString inspectorEnv = QString::fromUtf8(qgetenv("QTWEBENGINE_REMOTE_DEBUGGING")); const base::CommandLine &commandLine = *base::CommandLine::ForCurrentProcess(); @@ -215,21 +130,56 @@ DevToolsHttpHandlerDelegateQt::DevToolsHttpHandlerDelegateQt() return; m_port = portStr.toInt(&m_valid); - m_valid = m_valid && m_port > 0 && m_port < 65535; + 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)); } -void DevToolsHttpHandlerDelegateQt::Initialized(const net::IPEndPoint *ip_address) +std::unique_ptr<content::DevToolsSocketFactory> DevToolsServerQt::CreateSocketFactory() +{ + if (!m_valid) + return nullptr; + return std::unique_ptr<content::DevToolsSocketFactory>( + new TCPServerSocketFactory(m_bindAddress.toStdString(), m_port, 1)); +} + + +void DevToolsServerQt::start() +{ + if (m_isStarted) + return; + + if (!m_valid) + parseAddressAndPort(); + + std::unique_ptr<content::DevToolsSocketFactory> socketFactory = CreateSocketFactory(); + if (!socketFactory) + return; + + m_isStarted = true; + DevToolsAgentHost::StartRemoteDebuggingServer( + std::move(socketFactory), std::string(), + base::FilePath(), base::FilePath(), + std::string(), std::string()); +} + +void DevToolsServerQt::stop() +{ + DevToolsAgentHost::StopRemoteDebuggingServer(); + m_isStarted = false; +} + +void DevToolsManagerDelegateQt::Initialized(const net::IPEndPoint *ip_address) { 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); + } + else + qWarning("Couldn't start the inspector server on bind address. 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)."); } -std::string DevToolsHttpHandlerDelegateQt::GetDiscoveryPageHTML() +std::string DevToolsManagerDelegateQt::GetDiscoveryPageHTML() { static std::string html; if (html.empty()) { @@ -241,24 +191,9 @@ std::string DevToolsHttpHandlerDelegateQt::GetDiscoveryPageHTML() return html; } -std::string DevToolsHttpHandlerDelegateQt::GetPageThumbnailData(const GURL& url) -{ - return std::string(); -} - -std::string DevToolsHttpHandlerDelegateQt::GetFrontendResource(const std::string &path) +std::string DevToolsManagerDelegateQt::GetFrontendResource(const std::string& path) { return content::DevToolsFrontendHost::GetFrontendResource(path).as_string(); } -content::DevToolsExternalAgentProxyDelegate* DevToolsHttpHandlerDelegateQt::HandleWebSocketConnection(const std::string&) -{ - return 0; -} - -base::DictionaryValue* DevToolsManagerDelegateQt::HandleCommand(DevToolsAgentHost *, base::DictionaryValue *) -{ - 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 6512146a5..1b0e82bc0 100644 --- a/src/core/dev_tools_http_handler_delegate_qt.h +++ b/src/core/dev_tools_http_handler_delegate_qt.h @@ -40,51 +40,45 @@ #ifndef DEV_TOOLS_HTTP_HANDLER_DELEGATE_QT_H #define DEV_TOOLS_HTTP_HANDLER_DELEGATE_QT_H -#include "components/devtools_http_handler/devtools_http_handler_delegate.h" #include "content/public/browser/devtools_manager_delegate.h" #include <QString> -#include <QtCore/qcompilerdetection.h> // needed for Q_DECL_OVERRIDE namespace content { -class BrowserContext; -} - -namespace devtools_http_handler { -class DevToolsHttpHandler; +class DevToolsSocketFactory; } namespace QtWebEngineCore { -std::unique_ptr<devtools_http_handler::DevToolsHttpHandler> createDevToolsHttpHandler(); - -class DevToolsHttpHandlerDelegateQt : public devtools_http_handler::DevToolsHttpHandlerDelegate { +class DevToolsServerQt { public: - DevToolsHttpHandlerDelegateQt(); + DevToolsServerQt(); + ~DevToolsServerQt(); 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; - - content::DevToolsExternalAgentProxyDelegate* HandleWebSocketConnection(const std::string&) Q_DECL_OVERRIDE; + void start(); + void stop(); + bool isStarted() const { return m_isStarted; } private: + void parseAddressAndPort(); + std::unique_ptr<content::DevToolsSocketFactory> CreateSocketFactory(); + QString m_bindAddress; int m_port; bool m_valid; + bool m_isStarted; }; + class DevToolsManagerDelegateQt : public content::DevToolsManagerDelegate { 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; + std::string GetDiscoveryPageHTML() override; + std::string GetFrontendResource(const std::string& path) override; + void Initialized(const net::IPEndPoint *ip_address) override; }; } // namespace QtWebEngineCore diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp index a1445d609..77469a8ea 100644 --- a/src/core/download_manager_delegate_qt.cpp +++ b/src/core/download_manager_delegate_qt.cpp @@ -61,16 +61,6 @@ namespace QtWebEngineCore { -ASSERT_ENUMS_MATCH(content::DownloadItem::IN_PROGRESS, BrowserContextAdapterClient::DownloadInProgress) -ASSERT_ENUMS_MATCH(content::DownloadItem::COMPLETE, BrowserContextAdapterClient::DownloadCompleted) -ASSERT_ENUMS_MATCH(content::DownloadItem::CANCELLED, BrowserContextAdapterClient::DownloadCancelled) -ASSERT_ENUMS_MATCH(content::DownloadItem::INTERRUPTED, BrowserContextAdapterClient::DownloadInterrupted) - -ASSERT_ENUMS_MATCH(content::SAVE_PAGE_TYPE_UNKNOWN, BrowserContextAdapterClient::UnknownSavePageFormat) -ASSERT_ENUMS_MATCH(content::SAVE_PAGE_TYPE_AS_ONLY_HTML, BrowserContextAdapterClient::SingleHtmlSaveFormat) -ASSERT_ENUMS_MATCH(content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML, BrowserContextAdapterClient::CompleteHtmlSaveFormat) -ASSERT_ENUMS_MATCH(content::SAVE_PAGE_TYPE_AS_MHTML, BrowserContextAdapterClient::MimeHtmlSaveFormat) - DownloadManagerDelegateQt::DownloadManagerDelegateQt(BrowserContextAdapter *contextAdapter) : m_contextAdapter(contextAdapter) , m_currentId(0) @@ -165,7 +155,8 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(content::DownloadItem* i suggestedFilePath, BrowserContextAdapterClient::UnknownSavePageFormat, false /* accepted */, - m_downloadType + m_downloadType, + item->GetLastReason() }; Q_FOREACH (BrowserContextAdapterClient *client, clients) { @@ -254,7 +245,8 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content suggestedFilePath, suggestedSaveFormat, acceptedByDefault, - BrowserContextAdapterClient::SavePage + BrowserContextAdapterClient::SavePage, + BrowserContextAdapterClient::NoReason }; Q_FOREACH (BrowserContextAdapterClient *client, clients) { @@ -291,7 +283,8 @@ void DownloadManagerDelegateQt::OnDownloadUpdated(content::DownloadItem *downloa QString(), BrowserContextAdapterClient::UnknownSavePageFormat, true /* accepted */, - m_downloadType + m_downloadType, + download->GetLastReason() }; Q_FOREACH (BrowserContextAdapterClient *client, clients) { diff --git a/src/core/gl_surface_qt.cpp b/src/core/gl_surface_qt.cpp index e8f77e9ed..30a915598 100644 --- a/src/core/gl_surface_qt.cpp +++ b/src/core/gl_surface_qt.cpp @@ -174,6 +174,26 @@ bool GLSurfaceGLX::IsCreateContextSupported() return ExtensionsContain(g_extensions, "GLX_ARB_create_context"); } +bool GLSurfaceGLX::IsCreateContextRobustnessSupported() +{ + return false; // ExtensionsContain(g_extensions, "GLX_ARB_create_context_robustness"); +} + +bool GLSurfaceGLX::IsCreateContextProfileSupported() +{ + return false; // ExtensionsContain(g_extensions, "GLX_ARB_create_context_profile"); +} + +bool GLSurfaceGLX::IsCreateContextES2ProfileSupported() +{ + return ExtensionsContain(g_extensions, "GLX_ARB_create_context_es2_profile"); +} + +bool GLSurfaceGLX::IsOMLSyncControlSupported() +{ + return false; // ExtensionsContain(g_extensions, "GLX_OML_sync_control"); +} + bool GLSurfaceGLX::HasGLXExtension(const char *name) { return ExtensionsContain(g_extensions, name); @@ -189,11 +209,6 @@ const char* GLSurfaceGLX::GetGLXExtensions() return g_extensions; } -bool GLSurfaceGLX::IsCreateContextRobustnessSupported() -{ - return false; -} - bool GLSurfaceQtGLX::InitializeOneOff() { static bool initialized = false; diff --git a/src/core/gn_run.pro b/src/core/gn_run.pro new file mode 100644 index 000000000..28d42aa13 --- /dev/null +++ b/src/core/gn_run.pro @@ -0,0 +1,61 @@ +isQtMinimum(5, 8) { + include($$QTWEBENGINE_OUT_ROOT/qtwebengine-config.pri) + QT_FOR_CONFIG += webengine-private +} + +TEMPLATE = aux + +defineReplace(runGn) { + message("Running: $$1") + !system($$1) { + error("GN run error!") + } +} + +qtConfig(debug_and_release): CONFIG += debug_and_release build_all + +build_pass|!debug_and_release { + + ninja_binary = ninja + gn_binary = gn + + runninja.target = run_ninja + rungn.target = run_gn + + gn_args = $$gnArgs() + + CONFIG(release, debug|release) { + gn_args += is_debug=false + } + + gn_args += "qtwebengine_target=\"$$shell_path($$OUT_PWD/$$getConfigDir()):QtWebEngineCore\"" + + !qtConfig(system-gn) { + gn_binary = $$shell_quote($$shell_path($$gnPath())) + } + + !qtConfig(system-ninja) { + ninja_binary = $$shell_quote($$shell_path($$ninjaPath())) + } + + gn_args = $$shell_quote($$gn_args) + gn_src_root = $$shell_quote($$shell_path($$QTWEBENGINE_ROOT/$$getChromiumSrcDir())) + gn_build_root = $$shell_quote($$shell_path($$OUT_PWD/$$getConfigDir())) + rungn.commands = $$runGn($$gn_binary gen $$gn_build_root --args=$$gn_args --root=$$gn_src_root) + QMAKE_EXTRA_TARGETS += rungn + + runninja.commands = $$ninja_binary \$\(NINJAFLAGS\) -C $$shell_quote($$OUT_PWD/$$getConfigDir()) QtWebEngineCore + runninja.depends += rungn + QMAKE_EXTRA_TARGETS += runninja + + build_pass:build_all: default_target.target = all + else: default_target.target = first + default_target.depends = runninja + QMAKE_EXTRA_TARGETS += default_target +} + +!build_pass:debug_and_release { + # Special GNU make target for the meta Makefile that ensures that our debug and release Makefiles won't both run ninja in parallel. + notParallel.target = .NOTPARALLEL + QMAKE_EXTRA_TARGETS += notParallel +} diff --git a/src/core/gyp_run.pro b/src/core/gyp_run.pro index dc22d14bf..2c6aa5069 100644 --- a/src/core/gyp_run.pro +++ b/src/core/gyp_run.pro @@ -2,9 +2,14 @@ # 1) invoking gyp through the gyp_qtwebengine script, which in turn makes use of the generated gypi include files # 2) produce a Makefile that will run ninja, and take care of actually building everything. +isQtMinimum(5, 8) { + include($$QTWEBENGINE_OUT_ROOT/qtwebengine-config.pri) + QT_FOR_CONFIG += webengine-private +} + TEMPLATE = aux -cross_compile { +contains(WEBENGINE_CONFIG, embedded_build) { GYP_ARGS = "-D qt_cross_compile=1" posix: GYP_ARGS += "-D os_posix=1" qnx: include(config/embedded_qnx.pri) @@ -148,13 +153,20 @@ for (config, GYP_CONFIG): GYP_ARGS += "-D $$config" } build_pass|!debug_and_release { - ninja.target = invoke_ninja - ninja.commands = $$findOrBuildNinja() \$\(NINJAFLAGS\) -C "$$OUT_PWD/$$getConfigDir()" - QMAKE_EXTRA_TARGETS += ninja + + ninja_binary = ninja + runninja.target = run_ninja + + !qtConfig(system-ninja) { + ninja_binary = $$shell_quote($$shell_path($$ninjaPath())) + } + + runninja.commands = $$ninja_binary \$\(NINJAFLAGS\) -C $$shell_quote($$OUT_PWD/$$getConfigDir()) + QMAKE_EXTRA_TARGETS += runninja build_pass:build_all: default_target.target = all else: default_target.target = first - default_target.depends = ninja + default_target.depends = runninja QMAKE_EXTRA_TARGETS += default_target } else { diff --git a/src/core/location_provider_qt.cpp b/src/core/location_provider_qt.cpp index c07bd4b0c..a507f32d1 100644 --- a/src/core/location_provider_qt.cpp +++ b/src/core/location_provider_qt.cpp @@ -51,9 +51,9 @@ #include "base/bind.h" #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" -#include "content/browser/geolocation/geolocation_provider_impl.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/geolocation_provider.h" +#include "device/geolocation/geolocation_provider.h" +#include "device/geolocation/geolocation_provider_impl.h" namespace QtWebEngineCore { @@ -161,8 +161,8 @@ void QtPositioningHelper::updatePosition(const QGeoPositionInfo &pos) if (!pos.isValid()) return; Q_ASSERT(m_positionInfoSource->error() == QGeoPositionInfoSource::NoError); - content::Geoposition newPos; - newPos.error_code = content::Geoposition::ERROR_CODE_NONE; + device::Geoposition newPos; + newPos.error_code = device::Geoposition::ERROR_CODE_NONE; newPos.error_message.clear(); newPos.timestamp = toTime(pos.timestamp()); @@ -195,15 +195,15 @@ void QtPositioningHelper::updatePosition(const QGeoPositionInfo &pos) void QtPositioningHelper::error(QGeoPositionInfoSource::Error positioningError) { Q_ASSERT(positioningError != QGeoPositionInfoSource::NoError); - content::Geoposition newPos; + device::Geoposition newPos; switch (positioningError) { case QGeoPositionInfoSource::AccessError: - newPos.error_code = content::Geoposition::ERROR_CODE_PERMISSION_DENIED; + newPos.error_code = device::Geoposition::ERROR_CODE_PERMISSION_DENIED; break; case QGeoPositionInfoSource::ClosedError: case QGeoPositionInfoSource::UnknownSourceError: // position unavailable is as good as it gets in Geoposition default: - newPos.error_code = content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; + newPos.error_code = device::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; break; } if (m_locationProvider) @@ -212,18 +212,18 @@ void QtPositioningHelper::error(QGeoPositionInfoSource::Error positioningError) void QtPositioningHelper::timeout() { - content::Geoposition newPos; + device::Geoposition newPos; // content::Geoposition::ERROR_CODE_TIMEOUT is not handled properly in the renderer process, and the timeout // argument used in JS never comes all the way to the browser process. // Let's just treat it like any other error where the position is unavailable. - newPos.error_code = content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; + newPos.error_code = device::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; if (m_locationProvider) postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, m_locationProviderFactory.GetWeakPtr(), newPos)); } inline void QtPositioningHelper::postToLocationProvider(const base::Closure &task) { - static_cast<content::GeolocationProviderImpl*>(content::GeolocationProvider::GetInstance())->message_loop()->PostTask(FROM_HERE, task); + static_cast<device::GeolocationProviderImpl*>(device::GeolocationProvider::GetInstance())->task_runner()->PostTask(FROM_HERE, task); } LocationProviderQt::LocationProviderQt() @@ -258,21 +258,21 @@ void LocationProviderQt::StopProvider() QMetaObject::invokeMethod(m_positioningHelper, "stop", Qt::QueuedConnection); } -void LocationProviderQt::RequestRefresh() +void LocationProviderQt::OnPermissionGranted() { if (m_positioningHelper) QMetaObject::invokeMethod(m_positioningHelper, "refresh", Qt::QueuedConnection); } -void LocationProviderQt::OnPermissionGranted() +void LocationProviderQt::SetUpdateCallback(const LocationProviderUpdateCallback& callback) { - RequestRefresh(); + m_callback = callback; } -void LocationProviderQt::updatePosition(const content::Geoposition &position) +void LocationProviderQt::updatePosition(const device::Geoposition &position) { m_lastKnownPosition = position; - NotifyCallback(position); + m_callback.Run(this, position); } } // namespace QtWebEngineCore diff --git a/src/core/location_provider_qt.h b/src/core/location_provider_qt.h index b35dcddf9..b1ff354a0 100644 --- a/src/core/location_provider_qt.h +++ b/src/core/location_provider_qt.h @@ -42,8 +42,8 @@ #include <QtCore/qcompilerdetection.h> -#include "content/browser/geolocation/location_provider_base.h" -#include "content/public/common/geoposition.h" +#include "device/geolocation/geoposition.h" +#include "device/geolocation/location_provider.h" QT_FORWARD_DECLARE_CLASS(QThread) @@ -54,25 +54,26 @@ class MessageLoop; namespace QtWebEngineCore { class QtPositioningHelper; -class LocationProviderQt : public content::LocationProviderBase +class LocationProviderQt : public device::LocationProvider { public: LocationProviderQt(); virtual ~LocationProviderQt(); - // LocationProviderBase - virtual bool StartProvider(bool highAccuracy) Q_DECL_OVERRIDE; - virtual void StopProvider() Q_DECL_OVERRIDE; - virtual void GetPosition(content::Geoposition *position) Q_DECL_OVERRIDE { *position = m_lastKnownPosition; } - virtual void RequestRefresh() Q_DECL_OVERRIDE; - virtual void OnPermissionGranted() Q_DECL_OVERRIDE; + // LocationProvider + bool StartProvider(bool high_accuracy) override; + void StopProvider() override; + const device::Geoposition& GetPosition() override { return m_lastKnownPosition; } + void OnPermissionGranted() override; + void SetUpdateCallback(const LocationProviderUpdateCallback& callback) override; private: friend class QtPositioningHelper; - void updatePosition(const content::Geoposition &); + void updatePosition(const device::Geoposition &); - content::Geoposition m_lastKnownPosition; + device::Geoposition m_lastKnownPosition; + LocationProviderUpdateCallback m_callback; QtPositioningHelper *m_positioningHelper; }; //#define QT_USE_POSITIONING 1 diff --git a/src/core/media_capture_devices_dispatcher.cpp b/src/core/media_capture_devices_dispatcher.cpp index f06f0150f..031171bcc 100644 --- a/src/core/media_capture_devices_dispatcher.cpp +++ b/src/core/media_capture_devices_dispatcher.cpp @@ -50,7 +50,7 @@ #include "web_engine_settings.h" #include "base/strings/utf_string_conversions.h" -#include "chrome/browser/media/desktop_streams_registry.h" +#include "chrome/browser/media/webrtc/desktop_streams_registry.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/desktop_media_id.h" #include "content/public/browser/media_capture_devices.h" diff --git a/src/core/ozone_platform_eglfs.cpp b/src/core/ozone_platform_eglfs.cpp index 0b560da6c..e6e1ab5e2 100644 --- a/src/core/ozone_platform_eglfs.cpp +++ b/src/core/ozone_platform_eglfs.cpp @@ -52,7 +52,6 @@ #include "ui/ozone/common/stub_overlay_manager.h" #include "ui/ozone/public/ozone_platform.h" #include "ui/ozone/public/cursor_factory_ozone.h" -#include "ui/ozone/public/gpu_platform_support.h" #include "ui/ozone/public/gpu_platform_support_host.h" #include "ui/platform_window/platform_window.h" #include "ui/platform_window/platform_window_delegate.h" @@ -140,10 +139,6 @@ ui::CursorFactoryOzone* OzonePlatformEglfs::GetCursorFactoryOzone() { return cursor_factory_ozone_.get(); } -GpuPlatformSupport* OzonePlatformEglfs::GetGpuPlatformSupport() { - return gpu_platform_support_.get(); -} - GpuPlatformSupportHost* OzonePlatformEglfs::GetGpuPlatformSupportHost() { return gpu_platform_support_host_.get(); } @@ -186,13 +181,12 @@ void OzonePlatformEglfs::InitializeUI() { device_manager_ = CreateDeviceManager(); cursor_factory_ozone_.reset(new CursorFactoryOzone()); event_factory_ozone_.reset(new EventFactoryEvdev(NULL, device_manager_.get(), NULL)); - gpu_platform_support_host_.reset(CreateStubGpuPlatformSupportHost()); + gpu_platform_support_host_.reset(ui::CreateStubGpuPlatformSupportHost()); input_controller_ = CreateStubInputController(); } void OzonePlatformEglfs::InitializeGPU() { surface_factory_ozone_.reset(new QtWebEngineCore::SurfaceFactoryQt()); - gpu_platform_support_.reset(CreateStubGpuPlatformSupport()); } } // namespace ui diff --git a/src/core/ozone_platform_eglfs.h b/src/core/ozone_platform_eglfs.h index cdc2bd1ce..c319b1e5c 100644 --- a/src/core/ozone_platform_eglfs.h +++ b/src/core/ozone_platform_eglfs.h @@ -59,7 +59,6 @@ class OzonePlatformEglfs : public OzonePlatform { virtual ui::SurfaceFactoryOzone* GetSurfaceFactoryOzone() override; virtual ui::CursorFactoryOzone* GetCursorFactoryOzone() override; - virtual GpuPlatformSupport* GetGpuPlatformSupport() override; virtual GpuPlatformSupportHost* GetGpuPlatformSupportHost() override; virtual std::unique_ptr<PlatformWindow> CreatePlatformWindow( PlatformWindowDelegate* delegate, @@ -78,7 +77,6 @@ class OzonePlatformEglfs : public OzonePlatform { std::unique_ptr<CursorFactoryOzone> cursor_factory_ozone_; std::unique_ptr<EventFactoryEvdev> event_factory_ozone_; - std::unique_ptr<GpuPlatformSupport> gpu_platform_support_; std::unique_ptr<GpuPlatformSupportHost> gpu_platform_support_host_; std::unique_ptr<InputController> input_controller_; std::unique_ptr<OverlayManagerOzone> overlay_manager_; diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp index f76f100e6..970a608a3 100644 --- a/src/core/permission_manager_qt.cpp +++ b/src/core/permission_manager_qt.cpp @@ -59,6 +59,7 @@ BrowserContextAdapter::PermissionType toQt(content::PermissionType type) return BrowserContextAdapter::AudioCapturePermission; case content::PermissionType::VIDEO_CAPTURE: return BrowserContextAdapter::VideoCapturePermission; + case content::PermissionType::FLASH: case content::PermissionType::NOTIFICATIONS: case content::PermissionType::MIDI_SYSEX: case content::PermissionType::PUSH_MESSAGING: @@ -110,6 +111,7 @@ bool PermissionManagerQt::checkPermission(const QUrl &origin, BrowserContextAdap int PermissionManagerQt::RequestPermission(content::PermissionType permission, content::RenderFrameHost *frameHost, const GURL& requesting_origin, + bool /*user_gesture*/, const base::Callback<void(blink::mojom::PermissionStatus)>& callback) { int request_id = ++m_requestIdCount; @@ -139,6 +141,7 @@ int PermissionManagerQt::RequestPermission(content::PermissionType permission, int PermissionManagerQt::RequestPermissions(const std::vector<content::PermissionType>& permissions, content::RenderFrameHost* frameHost, const GURL& requesting_origin, + bool /*user_gesture*/, const base::Callback<void(const std::vector<blink::mojom::PermissionStatus>&)>& callback) { NOTIMPLEMENTED() << "RequestPermissions has not been implemented in QtWebEngine"; diff --git a/src/core/permission_manager_qt.h b/src/core/permission_manager_qt.h index e4392b01c..1cbb41b5e 100644 --- a/src/core/permission_manager_qt.h +++ b/src/core/permission_manager_qt.h @@ -64,6 +64,7 @@ public: content::PermissionType permission, content::RenderFrameHost* render_frame_host, const GURL& requesting_origin, + bool user_gesture, const base::Callback<void(blink::mojom::PermissionStatus)>& callback) override; void CancelPermissionRequest(int request_id) override; @@ -82,6 +83,7 @@ public: const std::vector<content::PermissionType>& permission, content::RenderFrameHost* render_frame_host, const GURL& requesting_origin, + bool user_gesture, const base::Callback<void( const std::vector<blink::mojom::PermissionStatus>&)>& callback) override; diff --git a/src/core/print_view_manager_base_qt.cpp b/src/core/print_view_manager_base_qt.cpp index 8c52e1b18..63181e640 100644 --- a/src/core/print_view_manager_base_qt.cpp +++ b/src/core/print_view_manager_base_qt.cpp @@ -44,6 +44,8 @@ #include "type_conversion.h" #include "web_engine_context.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/timer/timer.h" #include "base/values.h" @@ -62,16 +64,6 @@ namespace QtWebEngineCore { -PrintViewManagerBaseQt::~PrintViewManagerBaseQt() -{ -} - -// PrintedPagesSource implementation. -base::string16 PrintViewManagerBaseQt::RenderSourceName() -{ - return toString16(QLatin1String("")); -} - PrintViewManagerBaseQt::PrintViewManagerBaseQt(content::WebContents *contents) : printing::PrintManager(contents) , m_isInsideInnerMessageLoop(false) @@ -79,84 +71,20 @@ PrintViewManagerBaseQt::PrintViewManagerBaseQt(content::WebContents *contents) , m_didPrintingSucceed(false) , m_printerQueriesQueue(WebEngineContext::current()->getPrintJobManager()->queue()) { - -} - -void PrintViewManagerBaseQt::OnNotifyPrintJobEvent( - const printing::JobEventDetails& event_details) { - switch (event_details.type()) { - case printing::JobEventDetails::FAILED: { - TerminatePrintJob(true); - - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_PRINT_JOB_RELEASED, - content::Source<content::WebContents>(web_contents()), - content::NotificationService::NoDetails()); - break; - } - case printing::JobEventDetails::USER_INIT_DONE: - case printing::JobEventDetails::DEFAULT_INIT_DONE: - case printing::JobEventDetails::USER_INIT_CANCELED: { - NOTREACHED(); - break; - } - case printing::JobEventDetails::ALL_PAGES_REQUESTED: { - break; - } - case printing::JobEventDetails::NEW_DOC: - case printing::JobEventDetails::NEW_PAGE: - case printing::JobEventDetails::PAGE_DONE: - case printing::JobEventDetails::DOC_DONE: { - // Don't care about the actual printing process. - break; - } - case printing::JobEventDetails::JOB_DONE: { - // Printing is done, we don't need it anymore. - // print_job_->is_job_pending() may still be true, depending on the order - // of object registration. - m_didPrintingSucceed = true; - ReleasePrintJob(); - - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_PRINT_JOB_RELEASED, - content::Source<content::WebContents>(web_contents()), - content::NotificationService::NoDetails()); - break; - } - default: { - NOTREACHED(); - break; - } - } } - -// content::WebContentsObserver implementation. -// Cancels the print job. -void PrintViewManagerBaseQt::NavigationStopped() +PrintViewManagerBaseQt::~PrintViewManagerBaseQt() { + ReleasePrinterQuery(); + DisconnectFromCurrentPrintJob(); } -// content::WebContentsObserver implementation. -void PrintViewManagerBaseQt::DidStartLoading() +void PrintViewManagerBaseQt::NavigationStopped() { + // Cancel the current job, wait for the worker to finish. + TerminatePrintJob(true); } -// content::NotificationObserver implementation. -void PrintViewManagerBaseQt::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - switch (type) { - case chrome::NOTIFICATION_PRINT_JOB_EVENT: - OnNotifyPrintJobEvent(*content::Details<printing::JobEventDetails>(details).ptr()); - break; - default: - NOTREACHED(); - break; - - } -} // Terminates or cancels the print job if one was pending. void PrintViewManagerBaseQt::RenderProcessGone(base::TerminationStatus status) { @@ -175,55 +103,11 @@ void PrintViewManagerBaseQt::RenderProcessGone(base::TerminationStatus status) } } -void PrintViewManagerBaseQt::ReleasePrinterQuery() { - if (!cookie_) - return; - - int cookie = cookie_; - cookie_ = 0; - - printing::PrintJobManager* printJobManager = - WebEngineContext::current()->getPrintJobManager(); - // May be NULL in tests. - if (!printJobManager) - return; - - scoped_refptr<printing::PrinterQuery> printerQuery; - printerQuery = m_printerQueriesQueue->PopPrinterQuery(cookie); - if (!printerQuery.get()) - return; - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::Bind(&printing::PrinterQuery::StopWorker, printerQuery.get())); -} - - -// content::WebContentsObserver implementation. -bool PrintViewManagerBaseQt::OnMessageReceived(const IPC::Message& message) +base::string16 PrintViewManagerBaseQt::RenderSourceName() { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(PrintViewManagerBaseQt, message) - IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintPage, OnDidPrintPage) - IPC_MESSAGE_HANDLER(PrintHostMsg_ShowInvalidPrinterSettingsError, - OnShowInvalidPrinterSettingsError); - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled || PrintManager::OnMessageReceived(message); -} - -void PrintViewManagerBaseQt::StopWorker(int documentCookie) { - if (documentCookie <= 0) - return; - scoped_refptr<printing::PrinterQuery> printer_query = - m_printerQueriesQueue->PopPrinterQuery(documentCookie); - if (printer_query.get()) { - content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, - base::Bind(&printing::PrinterQuery::StopWorker, - printer_query)); - } + return toString16(QLatin1String("")); } - // IPC handlers void PrintViewManagerBaseQt::OnDidPrintPage( const PrintHostMsg_DidPrintPage_Params& params) { @@ -304,121 +188,70 @@ void PrintViewManagerBaseQt::OnShowInvalidPrinterSettingsError() { } -bool PrintViewManagerBaseQt::CreateNewPrintJob(printing::PrintJobWorkerOwner* job) { - DCHECK(!m_isInsideInnerMessageLoop); - - // Disconnect the current print_job_. - DisconnectFromCurrentPrintJob(); - - // We can't print if there is no renderer. - if (!web_contents()->GetRenderViewHost() || - !web_contents()->GetRenderViewHost()->IsRenderViewLive()) { - return false; - } - - // Ask the renderer to generate the print preview, create the print preview - // view and switch to it, initialize the printer and show the print dialog. - DCHECK(!m_printJob.get()); - DCHECK(job); - if (!job) - return false; - - m_printJob = new printing::PrintJob(); - m_printJob->Initialize(job, this, number_pages_); - m_registrar.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT, - content::Source<printing::PrintJob>(m_printJob.get())); - m_didPrintingSucceed = false; - return true; -} - -void PrintViewManagerBaseQt::DisconnectFromCurrentPrintJob() { - // Make sure all the necessary rendered page are done. Don't bother with the - // return value. - bool result = RenderAllMissingPagesNow(); - - // Verify that assertion. - if (m_printJob.get() && - m_printJob->document() && - !m_printJob->document()->IsComplete()) { - DCHECK(!result); - // That failed. - TerminatePrintJob(true); - } else { - // DO NOT wait for the job to finish. - ReleasePrintJob(); - } -#if !defined(OS_MACOSX) - m_isExpectingFirstPage = true; -#endif +void PrintViewManagerBaseQt::DidStartLoading() +{ } -void PrintViewManagerBaseQt::PrintingDone(bool success) { - if (!m_printJob.get()) - return; - Send(new PrintMsg_PrintingDone(routing_id(), success)); +bool PrintViewManagerBaseQt::OnMessageReceived(const IPC::Message& message) +{ + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(PrintViewManagerBaseQt, message) + IPC_MESSAGE_HANDLER(PrintHostMsg_DidPrintPage, OnDidPrintPage) + IPC_MESSAGE_HANDLER(PrintHostMsg_ShowInvalidPrinterSettingsError, + OnShowInvalidPrinterSettingsError); + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled || PrintManager::OnMessageReceived(message); } -void PrintViewManagerBaseQt::TerminatePrintJob(bool cancel) { - if (!m_printJob.get()) - return; - - if (cancel) { - // We don't need the metafile data anymore because the printing is canceled. - m_printJob->Cancel(); - m_isInsideInnerMessageLoop = false; - } else { - DCHECK(!m_isInsideInnerMessageLoop); - DCHECK(!m_printJob->document() || m_printJob->document()->IsComplete()); - - // WebContents is either dying or navigating elsewhere. We need to render - // all the pages in an hurry if a print job is still pending. This does the - // trick since it runs a blocking message loop: - m_printJob->Stop(); - } - ReleasePrintJob(); +void PrintViewManagerBaseQt::Observe(int type, + const content::NotificationSource& /*source*/, + const content::NotificationDetails& details) +{ + DCHECK_EQ(chrome::NOTIFICATION_PRINT_JOB_EVENT, type); + OnNotifyPrintJobEvent(*content::Details<printing::JobEventDetails>(details).ptr()); } -bool PrintViewManagerBaseQt::OpportunisticallyCreatePrintJob(int cookie) +void PrintViewManagerBaseQt::OnNotifyPrintJobEvent(const printing::JobEventDetails& event_details) { - if (m_printJob.get()) - return true; - - if (!cookie) { - // Out of sync. It may happens since we are completely asynchronous. Old - // spurious message can happen if one of the processes is overloaded. - return false; - } - - // The job was initiated by a script. Time to get the corresponding worker - // thread. - scoped_refptr<printing::PrinterQuery> queued_query = m_printerQueriesQueue->PopPrinterQuery(cookie); - if (!queued_query.get()) { - NOTREACHED(); - return false; - } - - if (!CreateNewPrintJob(queued_query.get())) { - // Don't kill anything. - return false; + switch (event_details.type()) { + case printing::JobEventDetails::FAILED: + TerminatePrintJob(true); + + content::NotificationService::current()->Notify( + chrome::NOTIFICATION_PRINT_JOB_RELEASED, + content::Source<content::WebContents>(web_contents()), + content::NotificationService::NoDetails()); + break; + case printing::JobEventDetails::USER_INIT_DONE: + case printing::JobEventDetails::DEFAULT_INIT_DONE: + case printing::JobEventDetails::USER_INIT_CANCELED: + NOTREACHED(); + break; + case printing::JobEventDetails::ALL_PAGES_REQUESTED: + break; + case printing::JobEventDetails::NEW_DOC: + case printing::JobEventDetails::NEW_PAGE: + case printing::JobEventDetails::PAGE_DONE: + case printing::JobEventDetails::DOC_DONE: + // Don't care about the actual printing process. + break; + case printing::JobEventDetails::JOB_DONE: + // Printing is done, we don't need it anymore. + // print_job_->is_job_pending() may still be true, depending on the order + // of object registration. + m_didPrintingSucceed = true; + ReleasePrintJob(); + + content::NotificationService::current()->Notify( + chrome::NOTIFICATION_PRINT_JOB_RELEASED, + content::Source<content::WebContents>(web_contents()), + content::NotificationService::NoDetails()); + break; + default: + NOTREACHED(); + break; } - - // Settings are already loaded. Go ahead. This will set - // print_job_->is_job_pending() to true. - m_printJob->StartPrinting(); - return true; -} - -void PrintViewManagerBaseQt::ReleasePrintJob() { - if (!m_printJob.get()) - return; - - PrintingDone(m_didPrintingSucceed); - - m_registrar.Remove(this, chrome::NOTIFICATION_PRINT_JOB_EVENT, - content::Source<printing::PrintJob>(m_printJob.get())); - m_printJob->DisconnectSource(); - // Don't close the worker thread. - m_printJob = NULL; } // Requests the RenderView to render all the missing pages for the print job. @@ -461,6 +294,118 @@ bool PrintViewManagerBaseQt::RenderAllMissingPagesNow() return true; } +// Quits the current message loop if these conditions hold true: a document is +// loaded and is complete and waiting_for_pages_to_be_rendered_ is true. This +// function is called in DidPrintPage() or on ALL_PAGES_REQUESTED +// notification. The inner message loop is created was created by +// RenderAllMissingPagesNow(). +void PrintViewManagerBaseQt::ShouldQuitFromInnerMessageLoop() +{ + // Look at the reason. + DCHECK(m_printJob->document()); + if (m_printJob->document() && + m_printJob->document()->IsComplete() && + m_isInsideInnerMessageLoop) { + // We are in a message loop created by RenderAllMissingPagesNow. Quit from + // it. + base::MessageLoop::current()->QuitWhenIdle(); + m_isInsideInnerMessageLoop = false; + } +} + +bool PrintViewManagerBaseQt::CreateNewPrintJob(printing::PrintJobWorkerOwner* job) +{ + DCHECK(!m_isInsideInnerMessageLoop); + + // Disconnect the current print_job_. + DisconnectFromCurrentPrintJob(); + + // We can't print if there is no renderer. + if (!web_contents()->GetRenderViewHost() || + !web_contents()->GetRenderViewHost()->IsRenderViewLive()) { + return false; + } + + // Ask the renderer to generate the print preview, create the print preview + // view and switch to it, initialize the printer and show the print dialog. + DCHECK(!m_printJob.get()); + DCHECK(job); + if (!job) + return false; + + m_printJob = new printing::PrintJob(); + m_printJob->Initialize(job, this, number_pages_); + m_registrar.Add(this, chrome::NOTIFICATION_PRINT_JOB_EVENT, + content::Source<printing::PrintJob>(m_printJob.get())); + m_didPrintingSucceed = false; + return true; +} + +void PrintViewManagerBaseQt::DisconnectFromCurrentPrintJob() +{ + // Make sure all the necessary rendered page are done. Don't bother with the + // return value. + bool result = RenderAllMissingPagesNow(); + + // Verify that assertion. + if (m_printJob.get() && + m_printJob->document() && + !m_printJob->document()->IsComplete()) { + DCHECK(!result); + // That failed. + TerminatePrintJob(true); + } else { + // DO NOT wait for the job to finish. + ReleasePrintJob(); + } +#if !defined(OS_MACOSX) + m_isExpectingFirstPage = true; +#endif +} + +void PrintViewManagerBaseQt::PrintingDone(bool success) +{ + if (!m_printJob.get()) + return; + Send(new PrintMsg_PrintingDone(routing_id(), success)); +} + +void PrintViewManagerBaseQt::TerminatePrintJob(bool cancel) +{ + if (!m_printJob.get()) + return; + + if (cancel) { + // We don't need the metafile data anymore because the printing is canceled. + m_printJob->Cancel(); + m_isInsideInnerMessageLoop = false; + } else { + DCHECK(!m_isInsideInnerMessageLoop); + DCHECK(!m_printJob->document() || m_printJob->document()->IsComplete()); + + // WebContents is either dying or navigating elsewhere. We need to render + // all the pages in an hurry if a print job is still pending. This does the + // trick since it runs a blocking message loop: + m_printJob->Stop(); + } + ReleasePrintJob(); +} + +void PrintViewManagerBaseQt::ReleasePrintJob() +{ + if (!m_printJob.get()) + return; + + PrintingDone(m_didPrintingSucceed); + + m_registrar.Remove(this, chrome::NOTIFICATION_PRINT_JOB_EVENT, + content::Source<printing::PrintJob>(m_printJob.get())); + m_printJob->DisconnectSource(); + // Don't close the worker thread. + m_printJob = NULL; +} + + bool PrintViewManagerBaseQt::RunInnerMessageLoop() { // This value may actually be too low: // @@ -483,9 +428,11 @@ bool PrintViewManagerBaseQt::RunInnerMessageLoop() { // Need to enable recursive task. { - base::MessageLoop::ScopedNestableTaskAllower allow( - base::MessageLoop::current()); - base::MessageLoop::current()->Run(); + base::RunLoop runLoop; + m_quitClosure = runLoop.QuitClosure(); + base::MessageLoop* loop = base::MessageLoop::current(); + base::MessageLoop::ScopedNestableTaskAllower allowNested(loop); + runLoop.Run(); } bool success = true; @@ -498,23 +445,69 @@ bool PrintViewManagerBaseQt::RunInnerMessageLoop() { return success; } -// Quits the current message loop if these conditions hold true: a document is -// loaded and is complete and waiting_for_pages_to_be_rendered_ is true. This -// function is called in DidPrintPage() or on ALL_PAGES_REQUESTED -// notification. The inner message loop is created was created by -// RenderAllMissingPagesNow(). -void PrintViewManagerBaseQt::ShouldQuitFromInnerMessageLoop() +bool PrintViewManagerBaseQt::OpportunisticallyCreatePrintJob(int cookie) { - // Look at the reason. - DCHECK(m_printJob->document()); - if (m_printJob->document() && - m_printJob->document()->IsComplete() && - m_isInsideInnerMessageLoop) { - // We are in a message loop created by RenderAllMissingPagesNow. Quit from - // it. - base::MessageLoop::current()->QuitWhenIdle(); - m_isInsideInnerMessageLoop = false; + if (m_printJob.get()) + return true; + + if (!cookie) { + // Out of sync. It may happens since we are completely asynchronous. Old + // spurious message can happen if one of the processes is overloaded. + return false; } + + // The job was initiated by a script. Time to get the corresponding worker + // thread. + scoped_refptr<printing::PrinterQuery> queued_query = m_printerQueriesQueue->PopPrinterQuery(cookie); + if (!queued_query.get()) { + NOTREACHED(); + return false; + } + + if (!CreateNewPrintJob(queued_query.get())) { + // Don't kill anything. + return false; + } + + // Settings are already loaded. Go ahead. This will set + // print_job_->is_job_pending() to true. + m_printJob->StartPrinting(); + return true; +} + +void PrintViewManagerBaseQt::ReleasePrinterQuery() +{ + if (!cookie_) + return; + + int cookie = cookie_; + cookie_ = 0; + + printing::PrintJobManager* printJobManager = WebEngineContext::current()->getPrintJobManager(); + // May be NULL in tests. + if (!printJobManager) + return; + + scoped_refptr<printing::PrinterQuery> printerQuery; + printerQuery = m_printerQueriesQueue->PopPrinterQuery(cookie); + if (!printerQuery.get()) + return; + content::BrowserThread::PostTask( + content::BrowserThread::IO, FROM_HERE, + base::Bind(&printing::PrinterQuery::StopWorker, printerQuery.get())); +} + +// Originally from print_preview_message_handler.cc: +void PrintViewManagerBaseQt::StopWorker(int documentCookie) { + if (documentCookie <= 0) + return; + scoped_refptr<printing::PrinterQuery> printer_query = + m_printerQueriesQueue->PopPrinterQuery(documentCookie); + if (printer_query.get()) { + content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, + base::Bind(&printing::PrinterQuery::StopWorker, + printer_query)); + } } } // namespace QtWebEngineCore diff --git a/src/core/print_view_manager_base_qt.h b/src/core/print_view_manager_base_qt.h index a8b4b5fc8..27dda5ef6 100644 --- a/src/core/print_view_manager_base_qt.h +++ b/src/core/print_view_manager_base_qt.h @@ -135,6 +135,8 @@ protected: private: content::NotificationRegistrar m_registrar; scoped_refptr<printing::PrintJob> m_printJob; + // Closure for quitting nested message loop. + base::Closure m_quitClosure; bool m_isInsideInnerMessageLoop; bool m_isExpectingFirstPage; diff --git a/src/core/print_view_manager_qt.cpp b/src/core/print_view_manager_qt.cpp index 0231df8bd..6006c3bad 100644 --- a/src/core/print_view_manager_qt.cpp +++ b/src/core/print_view_manager_qt.cpp @@ -63,7 +63,8 @@ namespace { static const qreal kMicronsToMillimeter = 1000.0f; static std::vector<char> -GetStdVectorFromHandle(base::SharedMemoryHandle handle, uint32_t data_size) { +GetStdVectorFromHandle(base::SharedMemoryHandle handle, uint32_t data_size) +{ std::unique_ptr<base::SharedMemory> shared_buf( new base::SharedMemory(handle, true)); @@ -76,7 +77,8 @@ GetStdVectorFromHandle(base::SharedMemoryHandle handle, uint32_t data_size) { } static scoped_refptr<base::RefCountedBytes> -GetBytesFromHandle(base::SharedMemoryHandle handle, uint32_t data_size) { +GetBytesFromHandle(base::SharedMemoryHandle handle, uint32_t data_size) +{ std::unique_ptr<base::SharedMemory> shared_buf( new base::SharedMemory(handle, true)); @@ -91,7 +93,10 @@ GetBytesFromHandle(base::SharedMemoryHandle handle, uint32_t data_size) { // Write the PDF file to disk. static void SavePdfFile(scoped_refptr<base::RefCountedBytes> data, - const base::FilePath& path) { + const base::FilePath& path, + const QtWebEngineCore::PrintViewManagerQt::PrintToPDFFileCallback + &saveCallback) +{ DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); DCHECK_GT(data->size(), 0U); @@ -100,8 +105,10 @@ static void SavePdfFile(scoped_refptr<base::RefCountedBytes> data, base::File file(path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); - if (file.IsValid()) - metafile.SaveTo(&file); + bool success = file.IsValid() && metafile.SaveTo(&file); + content::BrowserThread::PostTask(content::BrowserThread::UI, + FROM_HERE, + base::Bind(saveCallback, success)); } static base::DictionaryValue *createPrintSettings() @@ -172,30 +179,43 @@ PrintViewManagerQt::~PrintViewManagerQt() } #if defined(ENABLE_BASIC_PRINTING) -bool PrintViewManagerQt::PrintToPDF(const QPageLayout &pageLayout, bool printInColor, const QString &filePath) +void PrintViewManagerQt::PrintToPDFFileWithCallback(const QPageLayout &pageLayout, + bool printInColor, const QString &filePath, + const PrintToPDFFileCallback& callback) { - if (m_printSettings || !filePath.length()) - return false; + if (callback.is_null()) + return; + + if (m_printSettings || !filePath.length()) { + content::BrowserThread::PostTask(content::BrowserThread::UI, + FROM_HERE, + base::Bind(callback, false)); + return; + } m_pdfOutputPath = toFilePath(filePath); + m_pdfSaveCallback = callback; if (!PrintToPDFInternal(pageLayout, printInColor)) { + content::BrowserThread::PostTask(content::BrowserThread::UI, + FROM_HERE, + base::Bind(callback, false)); resetPdfState(); - return false; } - return true; } -bool PrintViewManagerQt::PrintToPDFWithCallback(const QPageLayout &pageLayout, bool printInColor, const PrintToPDFCallback& callback) +void PrintViewManagerQt::PrintToPDFWithCallback(const QPageLayout &pageLayout, + bool printInColor, + const PrintToPDFCallback& callback) { if (callback.is_null()) - return false; + return; // If there already is a pending print in progress, don't try starting another one. if (m_printSettings) { content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, base::Bind(callback, std::vector<char>())); - return false; + return; } m_pdfPrintCallback = callback; @@ -205,9 +225,7 @@ bool PrintViewManagerQt::PrintToPDFWithCallback(const QPageLayout &pageLayout, b base::Bind(callback, std::vector<char>())); resetPdfState(); - return false; } - return true; } bool PrintViewManagerQt::PrintToPDFInternal(const QPageLayout &pageLayout, bool printInColor) @@ -218,7 +236,8 @@ bool PrintViewManagerQt::PrintToPDFInternal(const QPageLayout &pageLayout, bool m_printSettings.reset(createPrintSettingsFromQPageLayout(pageLayout)); m_printSettings->SetBoolean(printing::kSettingShouldPrintBackgrounds , web_contents()->GetRenderViewHost()->GetWebkitPreferences().should_print_backgrounds); - m_printSettings->SetInteger(printing::kSettingColor, printInColor ? printing::COLOR : printing::GRAYSCALE); + m_printSettings->SetInteger(printing::kSettingColor, + printInColor ? printing::COLOR : printing::GRAYSCALE); return Send(new PrintMsg_InitiatePrintPreview(routing_id(), false)); } @@ -255,6 +274,7 @@ void PrintViewManagerQt::resetPdfState() { m_pdfOutputPath.clear(); m_pdfPrintCallback.Reset(); + m_pdfSaveCallback.Reset(); m_printSettings.reset(); } @@ -273,20 +293,23 @@ void PrintViewManagerQt::OnMetafileReadyForPrinting( // Create local copies so we can reset the state and take a new pdf print job. base::Callback<void(const std::vector<char>&)> pdf_print_callback = m_pdfPrintCallback; + base::Callback<void(bool)> pdf_save_callback = m_pdfSaveCallback; base::FilePath pdfOutputPath = m_pdfOutputPath; resetPdfState(); if (!pdf_print_callback.is_null()) { - std::vector<char> data_vector = GetStdVectorFromHandle(params.metafile_data_handle, params.data_size); + std::vector<char> data_vector = GetStdVectorFromHandle(params.metafile_data_handle, + params.data_size); content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, base::Bind(pdf_print_callback, data_vector)); } else { - scoped_refptr<base::RefCountedBytes> data_bytes = GetBytesFromHandle(params.metafile_data_handle, params.data_size); + scoped_refptr<base::RefCountedBytes> data_bytes + = GetBytesFromHandle(params.metafile_data_handle, params.data_size); content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE, - base::Bind(&SavePdfFile, data_bytes, pdfOutputPath)); + base::Bind(&SavePdfFile, data_bytes, pdfOutputPath, pdf_save_callback)); } } diff --git a/src/core/print_view_manager_qt.h b/src/core/print_view_manager_qt.h index 668516096..b2ba73b27 100644 --- a/src/core/print_view_manager_qt.h +++ b/src/core/print_view_manager_qt.h @@ -81,10 +81,16 @@ class PrintViewManagerQt public: ~PrintViewManagerQt() override; typedef base::Callback<void(const std::vector<char> &result)> PrintToPDFCallback; + typedef base::Callback<void(bool success)> PrintToPDFFileCallback; #if defined(ENABLE_BASIC_PRINTING) // Method to print a page to a Pdf document with page size \a pageSize in location \a filePath. - bool PrintToPDF(const QPageLayout &pageLayout, bool printInColor, const QString &filePath); - bool PrintToPDFWithCallback(const QPageLayout &pageLayout, bool printInColor, const PrintToPDFCallback &callback); + void PrintToPDFFileWithCallback(const QPageLayout &pageLayout, + bool printInColor, + const QString &filePath, + const PrintToPDFFileCallback& callback); + void PrintToPDFWithCallback(const QPageLayout &pageLayout, + bool printInColor, + const PrintToPDFCallback &callback); #endif // ENABLE_BASIC_PRINTING // PrintedPagesSource implementation. @@ -114,6 +120,7 @@ protected: base::FilePath m_pdfOutputPath; PrintToPDFCallback m_pdfPrintCallback; + PrintToPDFFileCallback m_pdfSaveCallback; private: friend class content::WebContentsUserData<PrintViewManagerQt>; diff --git a/src/core/printing_message_filter_qt.cpp b/src/core/printing_message_filter_qt.cpp index a84ec491f..49940d7ee 100644 --- a/src/core/printing_message_filter_qt.cpp +++ b/src/core/printing_message_filter_qt.cpp @@ -111,6 +111,7 @@ void PrintingMessageFilterQt::OnGetDefaultPrintSettings(IPC::Message* reply_msg) false, printing::DEFAULT_MARGINS, false, + false, base::Bind(&PrintingMessageFilterQt::OnGetDefaultPrintSettingsReply, this, printer_query, @@ -156,6 +157,7 @@ void PrintingMessageFilterQt::OnScriptedPrint( params.has_selection, params.margin_type, params.is_scripted, + params.is_modifiable, base::Bind(&PrintingMessageFilterQt::OnScriptedPrintReply, this, printer_query, diff --git a/src/core/qtwebengine.gni b/src/core/qtwebengine.gni new file mode 100644 index 000000000..8fa018038 --- /dev/null +++ b/src/core/qtwebengine.gni @@ -0,0 +1,44 @@ +import("//third_party/widevine/cdm/widevine.gni") + +chromium_version = exec_script("//build/util/version.py", [ "-f", rebase_path("//chrome/VERSION"), + "-t", "@MAJOR@.@MINOR@.@BUILD@.@PATCH@"], + "list lines") + +include_dirs = [ + "//skia/config", + "//third_party/skia/include/core" +] + +deps = [ + "//base", + "//components/error_page/common", + "//components/keyed_service/content", + "//components/visitedlink/browser", + "//components/visitedlink/renderer", + "//components/web_cache/browser", + "//components/web_cache/renderer", + "//content/public/app:browser", + "//content/public/browser", + "//content/public/common", + "//content/public/renderer", + "//net:net_browser_services", + "//skia", + "//third_party/WebKit/public:blink", + "//third_party/widevine/cdm:version_h", + "//ui/accessibility", + "//third_party/mesa:mesa_headers", + ":qtwebengine_sources", + ":qtwebengine_resources" +] + +if (enable_widevine) { + deps += [ "//components/cdm/renderer"] +} + +if (is_linux && !is_desktop_linux) { + deps += [ "//ui/events/ozone:events_ozone_evdev"] +} + +defines = [ + "CHROMIUM_VERSION=\"" + chromium_version[0] + "\"" +] diff --git a/src/core/qtwebengine.gypi b/src/core/qtwebengine.gypi index cd8d9cb5d..b83b1cbfa 100644 --- a/src/core/qtwebengine.gypi +++ b/src/core/qtwebengine.gypi @@ -131,16 +131,6 @@ '<(chromium_src_dir)/components/components.gyp:printing_browser', '<(chromium_src_dir)/components/components.gyp:printing_common', '<(chromium_src_dir)/components/components.gyp:printing_renderer', - ], - 'sources': [ - 'printing_message_filter_qt.cpp', - 'print_view_manager_base_qt.cpp', - 'print_view_manager_qt.cpp', - 'printing_message_filter_qt.h', - 'print_view_manager_base_qt.h', - 'print_view_manager_qt.h', - 'renderer/print_web_view_helper_delegate_qt.cpp', - 'renderer/print_web_view_helper_delegate_qt.h', ] }], ['icu_use_data_file_flag==1', { diff --git a/src/core/qtwebengine_resources.gni b/src/core/qtwebengine_resources.gni new file mode 100644 index 000000000..a7ffb40f3 --- /dev/null +++ b/src/core/qtwebengine_resources.gni @@ -0,0 +1,86 @@ +import("//tools/grit/repack.gni") +import("//build/config/locales.gni") +import("//chrome/chrome_repack_locales.gni") + +group("qtwebengine_resources") { + deps = [ + "//chrome/app:generated_resources", + "//components/resources:components_resources", + ":qtwebengine_repack_resources", + ":qtwebengine_repack_resources_100", + ":qtwebengine_repack_resources_200", + ":qtwebengine_repack_resources_devtools", + ":qtwebengine_repack_locales_pack" + ] +} + +repack("qtwebengine_repack_resources") { + sources = [ + "$root_gen_dir/blink/public/resources/blink_resources.pak", + "$root_gen_dir/components/components_resources.pak", + "$root_gen_dir/content/content_resources.pak", + "$root_gen_dir/net/net_resources.pak", + "$root_gen_dir/ui/resources/webui_resources.pak", + ] + output = "$root_out_dir/qtwebengine_resources.pak" + deps = [ + "//components/resources:components_resources_grit", + "//content:resources_grit", + "//net:net_resources_grit", + "//third_party/WebKit/public:resources_grit", + "//ui/resources:webui_resources_grd_grit", + ] +} + +repack("qtwebengine_repack_resources_100") { + sources = [ + "$root_gen_dir/ui/resources/ui_resources_100_percent.pak", + "$root_gen_dir/components/components_resources_100_percent.pak", + "$root_gen_dir/content/app/resources/content_resources_100_percent.pak", + "$root_gen_dir/chrome/renderer_resources_100_percent.pak", + "$root_gen_dir/blink/public/resources/blink_image_resources_100_percent.pak", + ] + output = "$root_out_dir/qtwebengine_resources_100p.pak" + deps = [ + "//third_party/WebKit/public:image_resources_grit", + "//chrome/renderer:resources_grit", + "//components/resources:components_scaled_resources_grit", + "//content/app/resources:resources_grit", + "//ui/resources:ui_resources_grd_grit" + ] +} + +repack("qtwebengine_repack_resources_200") { + sources = [ + "$root_gen_dir/ui/resources/ui_resources_200_percent.pak", + "$root_gen_dir/components/components_resources_200_percent.pak", + "$root_gen_dir/content/app/resources/content_resources_200_percent.pak", + "$root_gen_dir/chrome/renderer_resources_200_percent.pak", + "$root_gen_dir/blink/public/resources/blink_image_resources_200_percent.pak", + ] + output = "$root_out_dir/qtwebengine_resources_200p.pak" + deps = [ + "//third_party/WebKit/public:image_resources_grit", + "//chrome/renderer:resources_grit", + "//components/resources:components_scaled_resources_grit", + "//content/app/resources:resources_grit", + "//ui/resources:ui_resources_grd_grit" + ] +} + +repack("qtwebengine_repack_resources_devtools") { + sources = [ + "$root_gen_dir/blink/devtools_resources.pak", + ] + output = "$root_out_dir/qtwebengine_devtools_resources.pak" + deps = [ + "//content/browser/devtools:devtools_resources_grit" + ] +} + +chrome_repack_locales("qtwebengine_repack_locales_pack") { + input_locales = locales + output_dir = "$root_out_dir/qtwebengine_locales" + output_locales = locales +} + diff --git a/src/core/qtwebengine_sources.gni b/src/core/qtwebengine_sources.gni new file mode 100644 index 000000000..93a0feb72 --- /dev/null +++ b/src/core/qtwebengine_sources.gni @@ -0,0 +1,101 @@ +import("//build/config/features.gni") + +source_set("qtwebengine_spellcheck_sources") { + sources = [ + "//chrome/browser/spellchecker/spellcheck_custom_dictionary.cc", + "//chrome/browser/spellchecker/spellcheck_custom_dictionary.h", + "//chrome/browser/spellchecker/spellcheck_factory.cc", + "//chrome/browser/spellchecker/spellcheck_factory.h", + "//chrome/browser/spellchecker/spellcheck_hunspell_dictionary.cc", + "//chrome/browser/spellchecker/spellcheck_hunspell_dictionary.h", + "//chrome/browser/spellchecker/spellcheck_message_filter.cc", + "//chrome/browser/spellchecker/spellcheck_message_filter.h", + "//chrome/browser/spellchecker/spellcheck_service.cc", + "//chrome/browser/spellchecker/spellcheck_service.h", + ] + deps = [ + "//components/spellcheck/browser", + "//components/spellcheck/renderer", + "//third_party/WebKit/public:blink", + "//third_party/hunspell", + ] + if (is_mac && use_browser_spellchecker) { + sources += [ + "//chrome/browser/spellchecker/spellcheck_message_filter_platform.h", + "//chrome/browser/spellchecker/spellcheck_message_filter_platform_mac.cc", + ] + } +} + +source_set("qtwebengine_sources") { + include_dirs = [ + "//skia/config", + "//third_party/skia/include/core" + ] + deps = [] + sources = [ + "//chrome/browser/media/webrtc/desktop_media_list.h", + "//chrome/browser/media/webrtc/desktop_streams_registry.cc", + "//chrome/browser/media/webrtc/desktop_streams_registry.h", + "//chrome/common/chrome_switches.cc", + "//chrome/common/chrome_switches.h", + "//components/prefs/testing_pref_store.cc", + "//components/prefs/testing_pref_store.h", + "//extensions/common/constants.cc", + "//extensions/common/constants.h", + "//extensions/common/url_pattern.cc", + "//extensions/common/url_pattern.h", + ] + + if (enable_spellcheck) { + sources += [ + "//chrome/common/pref_names.cc", + "//chrome/common/pref_names.h", + ] + deps += [ + ":qtwebengine_spellcheck_sources", + "//chrome/tools/convert_dict", + ] + } + + if (enable_plugins) { + sources += [ + "//chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc", + "//chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h", + "//chrome/renderer/pepper/pepper_flash_font_file_host.cc", + "//chrome/renderer/pepper/pepper_flash_font_file_host.h", + "//chrome/renderer/pepper/pepper_shared_memory_message_filter.cc", + "//chrome/renderer/pepper/pepper_shared_memory_message_filter.h", + ] + + deps += [ + # Need to depend on //content/ppapi_plugin, which is private, thus depending on parent. + "//content", + ] + } + + if (enable_basic_printing || enable_print_preview) { + sources += [ + "//chrome/browser/printing/printer_query.cc", + "//chrome/browser/printing/printer_query.h", + "//chrome/browser/printing/print_job.cc", + "//chrome/browser/printing/print_job.h", + "//chrome/browser/printing/print_job_manager.cc", + "//chrome/browser/printing/print_job_manager.h", + "//chrome/browser/printing/print_job_worker.cc", + "//chrome/browser/printing/print_job_worker.h", + "//chrome/browser/printing/print_job_worker_owner.cc", + "//chrome/browser/printing/print_job_worker_owner.h", + ] + } + + if (enable_pdf) { + deps += [ + "//pdf", + "//components/printing/browser", + "//components/printing/renderer", + ] + } + +} + diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index a190380b2..f1c69fca3 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -52,10 +52,10 @@ #include "web_event_factory.h" #include "base/command_line.h" -#include "cc/output/compositor_frame_ack.h" +#include "cc/output/direct_renderer.h" #include "content/browser/accessibility/browser_accessibility_state_impl.h" -#include "content/browser/renderer_host/input/web_input_event_util.h" #include "content/browser/renderer_host/render_view_host_impl.h" +#include "content/browser/renderer_host/text_input_manager.h" #include "content/common/cursors/webcursor.h" #include "content/public/browser/browser_accessibility_state.h" #include "content/public/browser/browser_thread.h" @@ -241,9 +241,10 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost* widget , m_currentInputType(ui::TEXT_INPUT_TYPE_NONE) , m_imeInProgress(false) , m_receivedEmptyImeText(false) - , m_anchorPositionWithinSelection(0) - , m_cursorPositionWithinSelection(0) , m_initPending(false) + , m_beginFrameSource(nullptr) + , m_needsBeginFrames(false) + , m_addedFrameObserver(false) { m_host->SetView(this); #ifndef QT_NO_ACCESSIBILITY @@ -251,6 +252,9 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost* widget if (QAccessible::isActive()) content::BrowserAccessibilityStateImpl::GetInstance()->EnableAccessibility(); #endif // QT_NO_ACCESSIBILITY + auto* task_runner = base::ThreadTaskRunnerHandle::Get().get(); + m_beginFrameSource.reset(new cc::DelayBasedBeginFrameSource( + base::MakeUnique<cc::DelayBasedTimeSource>(task_runner))); } RenderWidgetHostViewQt::~RenderWidgetHostViewQt() @@ -610,22 +614,6 @@ void RenderWidgetHostViewQt::SetTooltipText(const base::string16 &tooltip_text) m_adapterClient->setToolTip(toQt(tooltip_text)); } -void RenderWidgetHostViewQt::SelectionBoundsChanged(const ViewHostMsg_SelectionBounds_Params ¶ms) -{ - if (selection_range_.IsValid()) { - if (params.is_anchor_first) { - m_anchorPositionWithinSelection = selection_range_.GetMin() - selection_text_offset_; - m_cursorPositionWithinSelection = selection_range_.GetMax() - selection_text_offset_; - } else { - m_anchorPositionWithinSelection = selection_range_.GetMax() - selection_text_offset_; - m_cursorPositionWithinSelection = selection_range_.GetMin() - selection_text_offset_; - } - } - - gfx::Rect caretRect = gfx::UnionRects(params.anchor_rect, params.focus_rect); - m_cursorRect = QRect(caretRect.x(), caretRect.y(), caretRect.width(), caretRect.height()); -} - void RenderWidgetHostViewQt::CopyFromCompositingSurface(const gfx::Rect& src_subrect, const gfx::Size& dst_size, const content::ReadbackRequestCallback& callback, const SkColorType color_type) { NOTIMPLEMENTED(); @@ -670,6 +658,8 @@ void RenderWidgetHostViewQt::OnSwapCompositorFrame(uint32_t output_surface_id, c m_pendingOutputSurfaceId = output_surface_id; Q_ASSERT(frame.delegated_frame_data); Q_ASSERT(!m_chromiumCompositorData->frameData || m_chromiumCompositorData->frameData->resource_list.empty()); + if (m_chromiumCompositorData->frameData.get()) + m_chromiumCompositorData->previousFrameData = std::move(m_chromiumCompositorData->frameData); m_chromiumCompositorData->frameData = std::move(frame.delegated_frame_data); m_chromiumCompositorData->frameDevicePixelRatio = frame.metadata.device_scale_factor; @@ -693,7 +683,7 @@ void RenderWidgetHostViewQt::OnSwapCompositorFrame(uint32_t output_surface_id, c m_adapterClient->updateContentsSize(toQt(m_lastContentsSize)); } -void RenderWidgetHostViewQt::GetScreenInfo(blink::WebScreenInfo* results) +void RenderWidgetHostViewQt::GetScreenInfo(content::ScreenInfo* results) { QWindow* window = m_delegate->window(); if (!window) @@ -701,7 +691,7 @@ void RenderWidgetHostViewQt::GetScreenInfo(blink::WebScreenInfo* results) GetScreenInfoFromNativeWindow(window, results); // Support experimental.viewport.devicePixelRatio - results->deviceScaleFactor *= dpiScale(); + results->device_scale_factor *= dpiScale(); } gfx::Rect RenderWidgetHostViewQt::GetBoundsInRootWindow() @@ -826,23 +816,34 @@ bool RenderWidgetHostViewQt::forwardEvent(QEvent *event) return true; } -QVariant RenderWidgetHostViewQt::inputMethodQuery(Qt::InputMethodQuery query) const +QVariant RenderWidgetHostViewQt::inputMethodQuery(Qt::InputMethodQuery query) { switch (query) { case Qt::ImEnabled: return QVariant(m_currentInputType != ui::TEXT_INPUT_TYPE_NONE); - case Qt::ImCursorRectangle: - return m_cursorRect; case Qt::ImFont: return QVariant(); + case Qt::ImCursorRectangle: + // QIBusPlatformInputContext might query ImCursorRectangle before the + // RenderWidgetHostView is created. Without an available view GetSelectionRange() + // returns nullptr. + if (!GetTextInputManager()->GetSelectionRegion()) + return QVariant(); + return toQt(GetTextInputManager()->GetSelectionRegion()->caret_rect); case Qt::ImCursorPosition: - return static_cast<uint>(m_cursorPositionWithinSelection); + Q_ASSERT(GetTextInputManager()->GetSelectionRegion()); + return toQt(GetTextInputManager()->GetSelectionRegion()->focus.edge_top_rounded().x()); case Qt::ImAnchorPosition: - return static_cast<uint>(m_anchorPositionWithinSelection); + Q_ASSERT(GetTextInputManager()->GetSelectionRegion()); + return toQt(GetTextInputManager()->GetSelectionRegion()->anchor.edge_top_rounded().x()); case Qt::ImSurroundingText: return m_surroundingText; - case Qt::ImCurrentSelection: - return toQt(GetSelectedText()); + case Qt::ImCurrentSelection: { + Q_ASSERT(GetTextInputManager()->GetTextSelection()); + base::string16 text; + GetTextInputManager()->GetTextSelection()->GetSelectedText(&text); + return toQt(text); + } case Qt::ImMaximumTextLength: return QVariant(); // No limit. case Qt::ImHints: @@ -860,11 +861,12 @@ void RenderWidgetHostViewQt::ProcessAckedTouchEvent(const content::TouchEventWit void RenderWidgetHostViewQt::sendDelegatedFrameAck() { - cc::CompositorFrameAck ack; - m_resourcesToRelease.swap(ack.resources); - content::RenderWidgetHostImpl::SendSwapCompositorFrameAck( + m_beginFrameSource->DidFinishFrame(this, 0); + cc::ReturnedResourceArray resources; + m_resourcesToRelease.swap(resources); + content::RenderWidgetHostImpl::SendReclaimCompositorResources( m_host->GetRoutingID(), m_pendingOutputSurfaceId, - m_host->GetProcess()->GetID(), ack); + m_host->GetProcess()->GetID(), true, resources); } void RenderWidgetHostViewQt::processMotionEvent(const ui::MotionEvent &motionEvent) @@ -918,7 +920,7 @@ void RenderWidgetHostViewQt::handleMouseEvent(QMouseEvent* event) blink::WebMouseEvent webEvent = WebEventFactory::toWebMouseEvent(event, dpiScale()); if ((webEvent.type == blink::WebInputEvent::MouseDown || webEvent.type == blink::WebInputEvent::MouseUp) - && webEvent.button == blink::WebMouseEvent::ButtonNone) { + && webEvent.button == blink::WebMouseEvent::Button::NoButton) { // Blink can only handle the 3 main mouse-buttons and may assert when processing mouse-down for no button. return; } @@ -978,9 +980,7 @@ void RenderWidgetHostViewQt::handleKeyEvent(QKeyEvent *ev) gfx::Range::InvalidRange(), gfx::Range::InvalidRange().start(), gfx::Range::InvalidRange().end()); - m_host->ImeConfirmComposition(base::string16(), - gfx::Range::InvalidRange(), - false); + m_host->ImeFinishComposingText(false); m_imeInProgress = false; } return; @@ -1097,7 +1097,7 @@ void RenderWidgetHostViewQt::handleInputMethodEvent(QInputMethodEvent *ev) if (!commitString.isEmpty() || replacementLength > 0) { setCompositionString(commitString); - m_host->ImeConfirmComposition(base::string16(), gfx::Range::InvalidRange(), false); + m_host->ImeFinishComposingText(false); // We might get a commit string and a pre-edit string in a single event, which means // we need to confirm the last composition, and start a new composition. @@ -1267,4 +1267,39 @@ void RenderWidgetHostViewQt::handleFocusEvent(QFocusEvent *ev) } } +void RenderWidgetHostViewQt::SetNeedsBeginFrames(bool needs_begin_frames) +{ + m_needsBeginFrames = needs_begin_frames; + updateNeedsBeginFramesInternal(); +} + +void RenderWidgetHostViewQt::updateNeedsBeginFramesInternal() +{ + if (!m_beginFrameSource) + return; + + if (m_addedFrameObserver == m_needsBeginFrames) + return; + + if (m_needsBeginFrames) + m_beginFrameSource->AddObserver(this); + else + m_beginFrameSource->RemoveObserver(this); + m_addedFrameObserver = m_needsBeginFrames; +} + +bool RenderWidgetHostViewQt::OnBeginFrameDerivedImpl(const cc::BeginFrameArgs& args) +{ + m_beginFrameSource->OnUpdateVSyncParameters(args.frame_time, args.interval); + m_host->Send(new ViewMsg_BeginFrame(m_host->GetRoutingID(), args)); + return true; +} + +void RenderWidgetHostViewQt::OnBeginFrameSourcePausedChanged(bool paused) +{ + // Ignored for now. If the begin frame source is paused, the renderer + // doesn't need to be informed about it and will just not receive more + // begin frames. +} + } // namespace QtWebEngineCore diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h index 2f5d97b67..8871d88ce 100644 --- a/src/core/render_widget_host_view_qt.h +++ b/src/core/render_widget_host_view_qt.h @@ -43,6 +43,7 @@ #include "render_widget_host_view_qt_delegate.h" #include "base/memory/weak_ptr.h" +#include "cc/scheduler/begin_frame_source.h" #include "cc/resources/transferable_resource.h" #include "content/browser/accessibility/browser_accessibility_manager.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" @@ -99,6 +100,7 @@ class RenderWidgetHostViewQt , public ui::GestureProviderClient , public RenderWidgetHostViewQtDelegateClient , public base::SupportsWeakPtr<RenderWidgetHostViewQt> + , public cc::BeginFrameObserverBase #ifndef QT_NO_ACCESSIBILITY , public QAccessible::ActivationObserver #endif // QT_NO_ACCESSIBILITY @@ -144,7 +146,6 @@ public: virtual void RenderProcessGone(base::TerminationStatus, int) Q_DECL_OVERRIDE; 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, const content::ReadbackRequestCallback& callback, const SkColorType preferred_color_type) Q_DECL_OVERRIDE; virtual void CopyFromCompositingSurfaceToVideoFrame(const gfx::Rect& src_subrect, const scoped_refptr<media::VideoFrame>& target, const base::Callback<void(const gfx::Rect&, bool)>& callback) Q_DECL_OVERRIDE; @@ -152,12 +153,13 @@ public: virtual bool HasAcceleratedSurface(const gfx::Size&) Q_DECL_OVERRIDE; virtual void OnSwapCompositorFrame(uint32_t output_surface_id, cc::CompositorFrame frame) Q_DECL_OVERRIDE; - virtual void GetScreenInfo(blink::WebScreenInfo* results) Q_DECL_OVERRIDE; + void GetScreenInfo(content::ScreenInfo* results); virtual gfx::Rect GetBoundsInRootWindow() Q_DECL_OVERRIDE; virtual void ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch, content::InputEventAckState ack_result) Q_DECL_OVERRIDE; virtual void ClearCompositorFrame() Q_DECL_OVERRIDE; virtual void LockCompositingSurface() Q_DECL_OVERRIDE; virtual void UnlockCompositingSurface() Q_DECL_OVERRIDE; + virtual void SetNeedsBeginFrames(bool needs_begin_frames) Q_DECL_OVERRIDE; // Overridden from RenderWidgetHostViewBase. virtual void SelectionChanged(const base::string16 &text, size_t offset, const gfx::Range &range) Q_DECL_OVERRIDE; @@ -173,7 +175,11 @@ public: virtual void windowBoundsChanged() Q_DECL_OVERRIDE; virtual void windowChanged() Q_DECL_OVERRIDE; virtual bool forwardEvent(QEvent *) Q_DECL_OVERRIDE; - virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const Q_DECL_OVERRIDE; + virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) Q_DECL_OVERRIDE; + + // cc::BeginFrameObserverBase implementation. + bool OnBeginFrameDerivedImpl(const cc::BeginFrameArgs& args) override; + void OnBeginFrameSourcePausedChanged(bool paused) override; void handleMouseEvent(QMouseEvent*); void handleKeyEvent(QKeyEvent*); @@ -210,6 +216,7 @@ private: void clearPreviousTouchMotionState(); QList<QTouchEvent::TouchPoint> mapTouchPointIds(const QList<QTouchEvent::TouchPoint> &inputPoints); float dpiScale() const; + void updateNeedsBeginFramesInternal(); bool IsPopup() const; @@ -235,13 +242,14 @@ private: ui::TextInputType m_currentInputType; bool m_imeInProgress; bool m_receivedEmptyImeText; - QRect m_cursorRect; - size_t m_anchorPositionWithinSelection; - size_t m_cursorPositionWithinSelection; QPoint m_lockedMousePosition; bool m_initPending; + std::unique_ptr<cc::SyntheticBeginFrameSource> m_beginFrameSource; + bool m_needsBeginFrames; + bool m_addedFrameObserver; + gfx::Vector2dF m_lastScrollOffset; gfx::SizeF m_lastContentsSize; diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h index 1e1234e72..6286596c6 100644 --- a/src/core/render_widget_host_view_qt_delegate.h +++ b/src/core/render_widget_host_view_qt_delegate.h @@ -84,7 +84,7 @@ public: virtual void windowBoundsChanged() = 0; virtual void windowChanged() = 0; virtual bool forwardEvent(QEvent *) = 0; - virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const = 0; + virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) = 0; }; class QWEBENGINE_EXPORT RenderWidgetHostViewQtDelegate { diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp index 69f5bfefe..ee6ffe420 100644 --- a/src/core/renderer/content_renderer_client_qt.cpp +++ b/src/core/renderer/content_renderer_client_qt.cpp @@ -44,8 +44,8 @@ #include "base/strings/string_split.h" #include "base/strings/utf_string_conversions.h" #if defined(ENABLE_SPELLCHECK) -#include "chrome/renderer/spellchecker/spellcheck.h" -#include "chrome/renderer/spellchecker/spellcheck_provider.h" +#include "components/spellcheck/renderer/spellcheck.h" +#include "components/spellcheck/renderer/spellcheck_provider.h" #endif #include "components/cdm/renderer/widevine_key_system_properties.h" #include "components/error_page/common/error_page_params.h" @@ -75,6 +75,7 @@ #include "renderer/render_frame_observer_qt.h" #include "renderer/render_view_observer_qt.h" #include "renderer/user_resource_controller.h" +#include "services/shell/public/cpp/interface_registry.h" #include "components/grit/components_resources.h" @@ -98,7 +99,8 @@ void ContentRendererClientQt::RenderThreadStarted() content::RenderThread *renderThread = content::RenderThread::Get(); m_visitedLinkSlave.reset(new visitedlink::VisitedLinkSlave); m_webCacheImpl.reset(new web_cache::WebCacheImpl()); - renderThread->AddObserver(m_visitedLinkSlave.data()); + renderThread->GetInterfaceRegistry()->AddInterface( + m_visitedLinkSlave->GetBindCallback()); renderThread->AddObserver(UserResourceController::instance()); #if defined(ENABLE_SPELLCHECK) diff --git a/src/core/renderer/user_resource_controller.cpp b/src/core/renderer/user_resource_controller.cpp index 8c603b805..c89ad69ad 100644 --- a/src/core/renderer/user_resource_controller.cpp +++ b/src/core/renderer/user_resource_controller.cpp @@ -39,6 +39,7 @@ #include "user_resource_controller.h" +#include "base/pending_task.h" #include "base/strings/pattern.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_view.h" @@ -166,16 +167,16 @@ UserResourceController::RenderViewObserverHelper::RenderViewObserverHelper(conte void UserResourceController::RenderViewObserverHelper::DidFinishDocumentLoad(blink::WebLocalFrame *frame) { m_pendingFrames.insert(frame); - base::MessageLoop::current()->PostDelayedTask(FROM_HERE, base::Bind(&UserResourceController::RenderViewObserverHelper::runScripts, - base::Unretained(this), UserScriptData::AfterLoad, frame), - base::TimeDelta::FromMilliseconds(afterLoadTimeout)); + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, base::Bind(&UserResourceController::RenderViewObserverHelper::runScripts, + base::Unretained(this), UserScriptData::AfterLoad, frame), + base::TimeDelta::FromMilliseconds(afterLoadTimeout)); } void UserResourceController::RenderViewObserverHelper::DidFinishLoad(blink::WebLocalFrame *frame) { // DidFinishDocumentLoad always comes before this, so frame has already been marked as pending. - base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&UserResourceController::RenderViewObserverHelper::runScripts, - base::Unretained(this), UserScriptData::AfterLoad, frame)); + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(&UserResourceController::RenderViewObserverHelper::runScripts, + base::Unretained(this), UserScriptData::AfterLoad, frame)); } void UserResourceController::RenderViewObserverHelper::DidStartProvisionalLoad(blink::WebLocalFrame *frame) diff --git a/src/core/renderer_host/pepper/pepper_isolated_file_system_message_filter.cpp b/src/core/renderer_host/pepper/pepper_isolated_file_system_message_filter.cpp index 7e8b2fdda..8ebc74486 100644 --- a/src/core/renderer_host/pepper/pepper_isolated_file_system_message_filter.cpp +++ b/src/core/renderer_host/pepper/pepper_isolated_file_system_message_filter.cpp @@ -83,7 +83,7 @@ scoped_refptr<base::TaskRunner> PepperIsolatedFileSystemMessageFilter::OverrideT { // In order to reach ExtensionSystem, we need to get ProfileManager first. // ProfileManager lives in UI thread, so we need to do this in UI thread. - return content::BrowserThread::GetMessageLoopProxyForThread(content::BrowserThread::UI); + return content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::UI); } int32_t PepperIsolatedFileSystemMessageFilter::OnResourceMessageReceived(const IPC::Message& msg, ppapi::host::HostMessageContext *context) diff --git a/src/core/ssl_host_state_delegate_qt.cpp b/src/core/ssl_host_state_delegate_qt.cpp index 506172aaa..72aec2bff 100644 --- a/src/core/ssl_host_state_delegate_qt.cpp +++ b/src/core/ssl_host_state_delegate_qt.cpp @@ -34,6 +34,8 @@ ** ****************************************************************************/ +#include "base/callback.h" + #include "ssl_host_state_delegate_qt.h" #include "type_conversion.h" @@ -86,9 +88,21 @@ void SSLHostStateDelegateQt::AllowCert(const std::string &host, const net::X509C } // Clear all allow preferences. -void SSLHostStateDelegateQt::Clear() +void SSLHostStateDelegateQt::Clear(const base::Callback<bool(const std::string&)>& host_filter) { - m_certPolicyforHost.clear(); + if (host_filter.is_null()) { + m_certPolicyforHost.clear(); + return; + } + + for (auto it = m_certPolicyforHost.begin(); it != m_certPolicyforHost.end();) { + auto next_it = std::next(it); + + if (host_filter.Run(it->first)) + m_certPolicyforHost.erase(it); + + it = next_it; + } } // Queries whether |cert| is allowed for |host| and |error|. Returns true in @@ -102,12 +116,12 @@ content::SSLHostStateDelegate::CertJudgment SSLHostStateDelegateQt::QueryPolicy( } // Records that a host has run insecure content. -void SSLHostStateDelegateQt::HostRanInsecureContent(const std::string &host, int pid) +void SSLHostStateDelegateQt::HostRanInsecureContent(const std::string &host, int pid, InsecureContentType content_type) { } // Returns whether the specified host ran insecure content. -bool SSLHostStateDelegateQt::DidHostRunInsecureContent(const std::string &host, int pid) const +bool SSLHostStateDelegateQt::DidHostRunInsecureContent(const std::string &host, int pid, InsecureContentType content_type) const { return false; } diff --git a/src/core/ssl_host_state_delegate_qt.h b/src/core/ssl_host_state_delegate_qt.h index 64a430094..7cc63b339 100644 --- a/src/core/ssl_host_state_delegate_qt.h +++ b/src/core/ssl_host_state_delegate_qt.h @@ -62,11 +62,11 @@ public: // content::SSLHostStateDelegate implementation: virtual void AllowCert(const std::string &, const net::X509Certificate &cert, net::CertStatus error) override; - virtual void Clear() override; + virtual void Clear(const base::Callback<bool(const std::string&)>& host_filter) override; virtual CertJudgment QueryPolicy(const std::string &host, const net::X509Certificate &cert, net::CertStatus error,bool *expired_previous_decision) override; - virtual void HostRanInsecureContent(const std::string &host, int pid) override; - virtual bool DidHostRunInsecureContent(const std::string &host, int pid) const override; + virtual void HostRanInsecureContent(const std::string& host, int child_id, InsecureContentType content_type) override; + virtual bool DidHostRunInsecureContent(const std::string& host, int child_id, InsecureContentType content_type) const override; virtual void RevokeUserAllowExceptions(const std::string &host) override; virtual bool HasAllowException(const std::string &host) const override; diff --git a/src/core/surface_factory_qt.cpp b/src/core/surface_factory_qt.cpp index 97a304730..36c05ec5d 100644 --- a/src/core/surface_factory_qt.cpp +++ b/src/core/surface_factory_qt.cpp @@ -71,7 +71,7 @@ base::NativeLibrary LoadLibrary(const base::FilePath& filename) { return library; } -bool SurfaceFactoryQt::LoadEGLGLES2Bindings(AddGLLibraryCallback add_gl_library, SetGLGetProcAddressProcCallback set_gl_get_proc_address) +bool SurfaceFactoryQt::LoadEGLGLES2Bindings() { base::FilePath libEGLPath = QtWebEngineCore::toFilePath(QT_LIBDIR_EGL); libEGLPath = libEGLPath.Append("libEGL.so.1"); diff --git a/src/core/surface_factory_qt.h b/src/core/surface_factory_qt.h index d65680a4a..ad6018946 100644 --- a/src/core/surface_factory_qt.h +++ b/src/core/surface_factory_qt.h @@ -51,7 +51,7 @@ namespace QtWebEngineCore { class SurfaceFactoryQt : public ui::SurfaceFactoryOzone { - virtual bool LoadEGLGLES2Bindings(AddGLLibraryCallback add_gl_library, SetGLGetProcAddressProcCallback set_gl_get_proc_address) Q_DECL_OVERRIDE; + virtual bool LoadEGLGLES2Bindings() Q_DECL_OVERRIDE; virtual intptr_t GetNativeDisplay() Q_DECL_OVERRIDE; }; diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp index 0cfde1cf4..635b7c2d0 100644 --- a/src/core/url_request_context_getter_qt.cpp +++ b/src/core/url_request_context_getter_qt.cpp @@ -173,8 +173,8 @@ void URLRequestContextGetterQt::updateStorageSettings() m_proxyConfigService = new ProxyConfigServiceQt( net::ProxyService::CreateSystemProxyConfigService( - content::BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), - content::BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE) + content::BrowserThread::GetTaskRunnerForThread(BrowserThread::IO), + content::BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE) )); if (m_contextInitialized) content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, @@ -477,7 +477,7 @@ void URLRequestContextGetterQt::generateHttpCache() net::CACHE_BACKEND_DEFAULT, base::FilePath(), m_httpCacheMaxSize, - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE) + BrowserThread::GetTaskRunnerForThread(BrowserThread::CACHE) ); break; case BrowserContextAdapter::DiskHttpCache: @@ -487,7 +487,7 @@ void URLRequestContextGetterQt::generateHttpCache() net::CACHE_BACKEND_DEFAULT, toFilePath(m_httpCachePath), m_httpCacheMaxSize, - BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE) + BrowserThread::GetTaskRunnerForThread(BrowserThread::CACHE) ); break; case BrowserContextAdapter::NoCache: @@ -600,7 +600,7 @@ void URLRequestContextGetterQt::regenerateJobFactory() scoped_refptr<base::SingleThreadTaskRunner> URLRequestContextGetterQt::GetNetworkTaskRunner() const { - return content::BrowserThread::GetMessageLoopProxyForThread(content::BrowserThread::IO); + return content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::IO); } } // namespace QtWebEngineCore diff --git a/src/core/url_request_qrc_job_qt.cpp b/src/core/url_request_qrc_job_qt.cpp index 97460f0b7..b4e960921 100644 --- a/src/core/url_request_qrc_job_qt.cpp +++ b/src/core/url_request_qrc_job_qt.cpp @@ -41,6 +41,8 @@ #include "type_conversion.h" +#include "base/pending_task.h" +#include "base/threading/thread_task_runner_handle.h" #include "net/base/net_errors.h" #include "net/base/io_buffer.h" @@ -67,7 +69,7 @@ URLRequestQrcJobQt::~URLRequestQrcJobQt() void URLRequestQrcJobQt::Start() { - base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&URLRequestQrcJobQt::startGetHead, m_weakFactory.GetWeakPtr())); + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(&URLRequestQrcJobQt::startGetHead, m_weakFactory.GetWeakPtr())); } void URLRequestQrcJobQt::Kill() diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index cff8a025a..7b0712143 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -77,6 +77,7 @@ #include "content/public/common/page_state.h" #include "content/public/common/page_zoom.h" #include "content/public/common/renderer_preferences.h" +#include "content/public/common/resource_request_body.h" #include "content/public/common/url_constants.h" #include "content/public/common/web_preferences.h" #include "third_party/WebKit/public/web/WebFindOptions.h" @@ -183,12 +184,23 @@ static void callbackOnEvaluateJS(WebContentsAdapterClient *adapterClient, quint6 adapterClient->didRunJavaScript(requestId, fromJSValue(result)); } -static void callbackOnPrintingFinished(WebContentsAdapterClient *adapterClient, int requestId, const std::vector<char>& result) +#if defined(ENABLE_BASIC_PRINTING) +static void callbackOnPrintingFinished(WebContentsAdapterClient *adapterClient, + int requestId, + const std::vector<char>& result) { if (requestId) adapterClient->didPrintPage(requestId, QByteArray(result.data(), result.size())); } +static void callbackOnPdfSavingFinished(WebContentsAdapterClient *adapterClient, + const QString& filePath, + bool success) +{ + adapterClient->didPrintPageToPdf(filePath, success); +} +#endif + static content::WebContents *createBlankWebContents(WebContentsAdapterClient *adapterClient, content::BrowserContext *browserContext) { content::WebContents::CreateParams create_params(browserContext, NULL); @@ -358,7 +370,7 @@ QSharedPointer<WebContentsAdapter> WebContentsAdapter::createFromSerializedNavig // Unlike WebCore, Chromium only supports Restoring to a new WebContents instance. content::WebContents* newWebContents = createBlankWebContents(adapterClient, adapterClient->browserContextAdapter()->browserContext()); content::NavigationController &controller = newWebContents->GetController(); - controller.Restore(currentIndex, content::NavigationController::RESTORE_LAST_SESSION_EXITED_CLEANLY, &entries); + controller.Restore(currentIndex, content::RestoreType::LAST_SESSION_EXITED_CLEANLY, &entries); if (controller.GetActiveEntry()) { // Set up the file access rights for the selected navigation entry. @@ -485,6 +497,12 @@ void WebContentsAdapter::reloadAndBypassCache() void WebContentsAdapter::load(const QUrl &url) { + QWebEngineHttpRequest request(url); + load(request); +} + +void WebContentsAdapter::load(const QWebEngineHttpRequest &request) +{ // The situation can occur when relying on the editingFinished signal in QML to set the url // of the WebView. // When enter is pressed, onEditingFinished fires and the url of the webview is set, which @@ -499,21 +517,55 @@ void WebContentsAdapter::load(const QUrl &url) Q_UNUSED(guard); Q_D(WebContentsAdapter); - GURL gurl = toGurl(url); + GURL gurl = toGurl(request.url()); // Add URL scheme if missing from view-source URL. - if (url.scheme() == content::kViewSourceScheme) { - QUrl pageUrl = QUrl(url.toString().remove(0, strlen(content::kViewSourceScheme) + 1)); + if (request.url().scheme() == content::kViewSourceScheme) { + QUrl pageUrl = QUrl(request.url().toString().remove(0, + strlen(content::kViewSourceScheme) + 1)); if (pageUrl.scheme().isEmpty()) { QUrl extendedUrl = QUrl::fromUserInput(pageUrl.toString()); - extendedUrl = QUrl(QString("%1:%2").arg(content::kViewSourceScheme, extendedUrl.toString())); + extendedUrl = QUrl(QString("%1:%2").arg(content::kViewSourceScheme, + extendedUrl.toString())); gurl = toGurl(extendedUrl); } } content::NavigationController::LoadURLParams params(gurl); - params.transition_type = ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR); + params.transition_type = ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED + | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR); params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE; + + switch (request.method()) { + case QWebEngineHttpRequest::Get: + params.load_type = content::NavigationController::LOAD_TYPE_DEFAULT; + break; + + case QWebEngineHttpRequest::Post: + params.load_type = content::NavigationController::LOAD_TYPE_HTTP_POST; + // chromium accepts LOAD_TYPE_HTTP_POST only for the HTTP and HTTPS protocols + if (!params.url.SchemeIsHTTPOrHTTPS()) { + d->adapterClient->loadFinished(false, request.url(), false, + net::ERR_DISALLOWED_URL_SCHEME, + QCoreApplication::translate("WebContentsAdapter", + "HTTP-POST data can only be sent over HTTP(S) protocol")); + return; + } + break; + } + + params.post_data = content::ResourceRequestBody::CreateFromBytes( + (const char*)request.postData().constData(), + request.postData().length()); + + // convert the custom headers into the format that chromium expects + QVector<QByteArray> headers = request.headers(); + for (QVector<QByteArray>::const_iterator it = headers.cbegin(); it != headers.cend(); ++it) { + if (params.extra_headers.length() > 0) + params.extra_headers += '\n'; + params.extra_headers += (*it).toStdString() + ": " + request.header(*it).toStdString(); + } + d->webContents->GetController().LoadURLWithParams(params); focusIfNecessary(); } @@ -560,15 +612,17 @@ QUrl WebContentsAdapter::activeUrl() const QUrl WebContentsAdapter::requestedUrl() const { Q_D(const WebContentsAdapter); - content::NavigationEntry* entry = d->webContents->GetController().GetVisibleEntry(); - content::NavigationEntry* pendingEntry = d->webContents->GetController().GetPendingEntry(); + if (d->webContents) { + content::NavigationEntry* entry = d->webContents->GetController().GetVisibleEntry(); + content::NavigationEntry* pendingEntry = d->webContents->GetController().GetPendingEntry(); - if (entry) { - if (!entry->GetOriginalRequestURL().is_empty()) - return toQt(entry->GetOriginalRequestURL()); + if (entry) { + if (!entry->GetOriginalRequestURL().is_empty()) + return toQt(entry->GetOriginalRequestURL()); - if (pendingEntry && pendingEntry == entry) - return toQt(entry->GetURL()); + if (pendingEntry && pendingEntry == entry) + return toQt(entry->GetURL()); + } } return QUrl(); } @@ -917,7 +971,7 @@ void WebContentsAdapter::inspectElementAt(const QPoint &location) { Q_D(WebContentsAdapter); if (content::DevToolsAgentHost::HasFor(d->webContents.get())) { - content::DevToolsAgentHost::GetOrCreateFor(d->webContents.get())->InspectElement(location.x(), location.y()); + content::DevToolsAgentHost::GetOrCreateFor(d->webContents.get())->InspectElement(nullptr, location.x(), location.y()); } } @@ -956,19 +1010,28 @@ void WebContentsAdapter::wasHidden() void WebContentsAdapter::printToPDF(const QPageLayout &pageLayout, const QString &filePath) { #if defined(ENABLE_BASIC_PRINTING) - PrintViewManagerQt::FromWebContents(webContents())->PrintToPDF(pageLayout, true, filePath); + Q_D(WebContentsAdapter); + PrintViewManagerQt::PrintToPDFFileCallback callback = base::Bind(&callbackOnPdfSavingFinished, + d->adapterClient, + filePath); + PrintViewManagerQt::FromWebContents(webContents())->PrintToPDFFileWithCallback(pageLayout, + true, + filePath, + callback); #endif // if defined(ENABLE_BASIC_PRINTING) } -quint64 WebContentsAdapter::printToPDFCallbackResult(const QPageLayout &pageLayout, const bool colorMode) +quint64 WebContentsAdapter::printToPDFCallbackResult(const QPageLayout &pageLayout, + const bool colorMode) { #if defined(ENABLE_BASIC_PRINTING) Q_D(WebContentsAdapter); - PrintViewManagerQt::PrintToPDFCallback callback = base::Bind(&callbackOnPrintingFinished - , d->adapterClient - , d->nextRequestId); - PrintViewManagerQt::FromWebContents(webContents())->PrintToPDFWithCallback(pageLayout, colorMode - , callback); + PrintViewManagerQt::PrintToPDFCallback callback = base::Bind(&callbackOnPrintingFinished, + d->adapterClient, + d->nextRequestId); + PrintViewManagerQt::FromWebContents(webContents())->PrintToPDFWithCallback(pageLayout, + colorMode, + callback); return d->nextRequestId++; #else return 0; @@ -1348,4 +1411,15 @@ bool WebContentsAdapter::canViewSource() return d->webContents->GetController().CanViewSource(); } +ASSERT_ENUMS_MATCH(WebContentsAdapterClient::UnknownDisposition, WindowOpenDisposition::UNKNOWN) +ASSERT_ENUMS_MATCH(WebContentsAdapterClient::CurrentTabDisposition, WindowOpenDisposition::CURRENT_TAB) +ASSERT_ENUMS_MATCH(WebContentsAdapterClient::SingletonTabDisposition, WindowOpenDisposition::SINGLETON_TAB) +ASSERT_ENUMS_MATCH(WebContentsAdapterClient::NewForegroundTabDisposition, WindowOpenDisposition::NEW_FOREGROUND_TAB) +ASSERT_ENUMS_MATCH(WebContentsAdapterClient::NewBackgroundTabDisposition, WindowOpenDisposition::NEW_BACKGROUND_TAB) +ASSERT_ENUMS_MATCH(WebContentsAdapterClient::NewPopupDisposition, WindowOpenDisposition::NEW_POPUP) +ASSERT_ENUMS_MATCH(WebContentsAdapterClient::NewWindowDisposition, WindowOpenDisposition::NEW_WINDOW) +ASSERT_ENUMS_MATCH(WebContentsAdapterClient::SaveToDiskDisposition, WindowOpenDisposition::SAVE_TO_DISK) +ASSERT_ENUMS_MATCH(WebContentsAdapterClient::OffTheRecordDisposition, WindowOpenDisposition::OFF_THE_RECORD) +ASSERT_ENUMS_MATCH(WebContentsAdapterClient::IgnoreActionDisposition, WindowOpenDisposition::IGNORE_ACTION) + } // namespace QtWebEngineCore diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h index 803b1eb57..10c65a6cb 100644 --- a/src/core/web_contents_adapter.h +++ b/src/core/web_contents_adapter.h @@ -42,6 +42,7 @@ #include "qtwebenginecoreglobal.h" #include "web_contents_adapter_client.h" +#include <QtWebEngineCore/qwebenginehttprequest.h> #include <QScopedPointer> #include <QSharedPointer> @@ -83,7 +84,8 @@ public: void stop(); void reload(); void reloadAndBypassCache(); - void load(const QUrl&); + void load(const QUrl &url); + void load(const QWebEngineHttpRequest &request); void setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl); void save(const QString &filePath = QString(), int savePageFormat = -1); QUrl activeUrl() const; diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index 4e15df753..d4b2974fc 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -254,16 +254,15 @@ public: // This must match window_open_disposition_list.h. enum WindowOpenDisposition { UnknownDisposition = 0, - SuppressOpenDisposition = 1, - CurrentTabDisposition = 2, - SingletonTabDisposition = 3, - NewForegroundTabDisposition = 4, - NewBackgroundTabDisposition = 5, - NewPopupDisposition = 6, - NewWindowDisposition = 7, - SaveToDiskDisposition = 8, - OffTheRecordDisposition = 9, - IgnoreActionDisposition = 10, + CurrentTabDisposition = 1, + SingletonTabDisposition = 2, + NewForegroundTabDisposition = 3, + NewBackgroundTabDisposition = 4, + NewPopupDisposition = 5, + NewWindowDisposition = 6, + SaveToDiskDisposition = 7, + OffTheRecordDisposition = 8, + IgnoreActionDisposition = 9, }; // Must match the values in javascript_message_type.h. @@ -347,6 +346,7 @@ public: virtual void didFetchDocumentInnerText(quint64 requestId, const QString& result) = 0; virtual void didFindText(quint64 requestId, int matchCount) = 0; virtual void didPrintPage(quint64 requestId, const QByteArray &result) = 0; + virtual void didPrintPageToPdf(const QString &filePath, bool success) = 0; virtual void passOnFocus(bool reverse) = 0; // returns the last QObject (QWidget/QQuickItem) based object in the accessibility // hierarchy before going into the BrowserAccessibility tree diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index 83fed35a0..fb32ea813 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -101,7 +101,7 @@ WebContentsDelegateQt::WebContentsDelegateQt(content::WebContents *webContents, content::WebContents *WebContentsDelegateQt::OpenURLFromTab(content::WebContents *source, const content::OpenURLParams ¶ms) { content::WebContents *target = source; - if (params.disposition != CURRENT_TAB) { + if (params.disposition != WindowOpenDisposition::CURRENT_TAB) { QSharedPointer<WebContentsAdapter> targetAdapter = createWindow(0, params.disposition, gfx::Rect(), params.user_gesture); if (targetAdapter) target = targetAdapter->webContents(); diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp index 24c4e198f..a8c6cca70 100644 --- a/src/core/web_contents_view_qt.cpp +++ b/src/core/web_contents_view_qt.cpp @@ -232,4 +232,11 @@ void WebContentsViewQt::TakeFocus(bool reverse) m_client->passOnFocus(reverse); } +void WebContentsViewQt::GetScreenInfo(content::ScreenInfo* results) const +{ + if (auto rwhv = static_cast<RenderWidgetHostViewQt *>(m_webContents->GetRenderWidgetHostView())) + rwhv->GetScreenInfo(results); +} + + } // namespace QtWebEngineCore diff --git a/src/core/web_contents_view_qt.h b/src/core/web_contents_view_qt.h index 48532c0c5..8d7d7a032 100644 --- a/src/core/web_contents_view_qt.h +++ b/src/core/web_contents_view_qt.h @@ -117,6 +117,8 @@ public: virtual void TakeFocus(bool reverse) Q_DECL_OVERRIDE; + virtual void GetScreenInfo(content::ScreenInfo* results) const Q_DECL_OVERRIDE; + #if defined(OS_MACOSX) virtual void SetAllowOtherViews(bool allow) Q_DECL_OVERRIDE { m_allowOtherViews = allow; } virtual bool GetAllowOtherViews() const Q_DECL_OVERRIDE { return m_allowOtherViews; } diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index b53234b45..78c0fa3b8 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -51,7 +51,7 @@ #if defined(ENABLE_BASIC_PRINTING) #include "chrome/browser/printing/print_job_manager.h" #endif // defined(ENABLE_BASIC_PRINTING) -#include "components/devtools_http_handler/devtools_http_handler.h" +#include "content/browser/devtools/devtools_http_handler.h" #include "content/browser/gpu/gpu_process_host.h" #include "content/browser/renderer_host/render_process_host_impl.h" #include "content/browser/utility_process_host_impl.h" @@ -185,13 +185,15 @@ void WebEngineContext::destroyBrowserContext() void WebEngineContext::destroy() { + if (m_devtoolsServer) + m_devtoolsServer->stop(); delete m_globalQObject; m_globalQObject = 0; base::MessagePump::Delegate *delegate = m_runLoop->loop_; // Flush the UI message loop before quitting. while (delegate->DoWork()) { } GLContextHelper::destroy(); - m_devtools.reset(0); + m_devtoolsServer.reset(0); m_runLoop->AfterRun(); // Force to destroy RenderProcessHostImpl by destroying BrowserMainRunner. @@ -207,7 +209,7 @@ WebEngineContext::~WebEngineContext() { // WebEngineContext::destroy() must be called before we are deleted Q_ASSERT(!m_globalQObject); - Q_ASSERT(!m_devtools); + Q_ASSERT(!m_devtoolsServer); Q_ASSERT(!m_browserRunner); } @@ -406,7 +408,8 @@ WebEngineContext::WebEngineContext() m_runLoop.reset(new base::RunLoop); m_runLoop->BeforeRun(); - m_devtools = createDevToolsHttpHandler(); + m_devtoolsServer.reset(new DevToolsServerQt()); + m_devtoolsServer->start(); // 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 878b651de..0058ccd84 100644 --- a/src/core/web_engine_context.h +++ b/src/core/web_engine_context.h @@ -56,10 +56,6 @@ class BrowserMainRunner; class ContentMainRunner; } -namespace devtools_http_handler { -class DevToolsHttpHandler; -} - #if defined(ENABLE_BASIC_PRINTING) namespace printing { class PrintJobManager; @@ -72,6 +68,7 @@ namespace QtWebEngineCore { class BrowserContextAdapter; class ContentMainDelegateQt; +class DevToolsServerQt; class SurfaceFactoryQt; class WebEngineContext : public base::RefCounted<WebEngineContext> { @@ -97,7 +94,7 @@ private: std::unique_ptr<content::BrowserMainRunner> m_browserRunner; QObject* m_globalQObject; QSharedPointer<QtWebEngineCore::BrowserContextAdapter> m_defaultBrowserContext; - std::unique_ptr<devtools_http_handler::DevToolsHttpHandler> m_devtools; + std::unique_ptr<DevToolsServerQt> m_devtoolsServer; #if defined(ENABLE_BASIC_PRINTING) std::unique_ptr<printing::PrintJobManager> m_printJobManager; #endif // defined(ENABLE_BASIC_PRINTING) diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp index 2e0669d4e..58f0a3e2c 100644 --- a/src/core/web_engine_settings.cpp +++ b/src/core/web_engine_settings.cpp @@ -242,6 +242,7 @@ void WebEngineSettings::initDefaults(bool offTheRecord) s_defaultAttributes.insert(FocusOnNavigationEnabled, true); s_defaultAttributes.insert(PrintElementBackgrounds, true); s_defaultAttributes.insert(AllowRunningInsecureContent, allowRunningInsecureContent); + s_defaultAttributes.insert(AllowGeolocationOnInsecureOrigins, false); } if (offTheRecord) m_attributes.insert(LocalStorageEnabled, false); @@ -325,6 +326,7 @@ void WebEngineSettings::applySettingsToWebPreferences(content::WebPreferences *p prefs->experimental_webgl_enabled = testAttribute(WebGLEnabled); prefs->should_print_backgrounds = testAttribute(PrintElementBackgrounds); prefs->allow_running_insecure_content = testAttribute(AllowRunningInsecureContent); + prefs->allow_geolocation_on_insecure_origins = testAttribute(AllowGeolocationOnInsecureOrigins); // 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 8459ba75b..4b0ce7b39 100644 --- a/src/core/web_engine_settings.h +++ b/src/core/web_engine_settings.h @@ -82,7 +82,8 @@ public: TouchIconsEnabled, FocusOnNavigationEnabled, PrintElementBackgrounds, - AllowRunningInsecureContent + AllowRunningInsecureContent, + AllowGeolocationOnInsecureOrigins }; // Must match the values from the public API in qwebenginesettings.h. diff --git a/src/core/web_engine_visited_links_manager.cpp b/src/core/web_engine_visited_links_manager.cpp index 0cf76d456..689c130e6 100644 --- a/src/core/web_engine_visited_links_manager.cpp +++ b/src/core/web_engine_visited_links_manager.cpp @@ -44,6 +44,7 @@ #include "content_browser_client_qt.h" #include "type_conversion.h" +#include <base/files/file_util.h> #include "components/visitedlink/browser/visitedlink_delegate.h" #include "components/visitedlink/browser/visitedlink_master.h" @@ -90,11 +91,28 @@ bool WebEngineVisitedLinksManager::containsUrl(const QUrl &url) const return m_visitedLinkMaster->IsVisited(toGurl(url)); } +static void ensureDirectoryExists(const base::FilePath &path) +{ + if (base::PathExists(path)) + return; + + base::File::Error error; + if (base::CreateDirectoryAndGetError(path, &error)) + return; + + std::string errorstr = base::File::ErrorToString(error); + qWarning("Cannot create directory %s. Error: %s.", + path.AsUTF8Unsafe().c_str(), + errorstr.c_str()); +} + WebEngineVisitedLinksManager::WebEngineVisitedLinksManager(BrowserContextAdapter *adapter) : m_delegate(new VisitedLinkDelegateQt) { Q_ASSERT(adapter && adapter->browserContext()); BrowserContextQt *browserContext = adapter->browserContext(); + if (adapter->persistVisitedLinks()) + ensureDirectoryExists(browserContext->GetPath()); m_visitedLinkMaster.reset(new visitedlink::VisitedLinkMaster(browserContext, m_delegate.data(), adapter->persistVisitedLinks())); m_visitedLinkMaster->Init(); } diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp index 9681ad629..ff5cc99a8 100644 --- a/src/core/web_event_factory.cpp +++ b/src/core/web_event_factory.cpp @@ -1036,25 +1036,25 @@ static inline double currentTimeForEvent(const QInputEvent* event) static WebMouseEvent::Button mouseButtonForEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) - return WebMouseEvent::ButtonLeft; + return WebMouseEvent::Button::Left; else if (event->button() == Qt::RightButton) - return WebMouseEvent::ButtonRight; + return WebMouseEvent::Button::Right; else if (event->button() == Qt::MidButton) - return WebMouseEvent::ButtonMiddle; + return WebMouseEvent::Button::Middle; if (event->type() != QEvent::MouseMove) - return WebMouseEvent::ButtonNone; + return WebMouseEvent::Button::NoButton; // This is technically wrong, mouse move should always have ButtonNone, // but it is consistent with aura and selection code depends on it: if (event->buttons() & Qt::LeftButton) - return WebMouseEvent::ButtonLeft; + return WebMouseEvent::Button::Left; else if (event->buttons() & Qt::RightButton) - return WebMouseEvent::ButtonRight; + return WebMouseEvent::Button::Right; else if (event->buttons() & Qt::MidButton) - return WebMouseEvent::ButtonMiddle; + return WebMouseEvent::Button::Middle; - return WebMouseEvent::ButtonNone; + return WebMouseEvent::Button::NoButton; } template <typename T> @@ -1247,7 +1247,6 @@ content::NativeWebKeyboardEvent WebEventFactory::toWebKeyboardEvent(QKeyEvent *e webKitEvent.nativeKeyCode = ev->nativeVirtualKey(); webKitEvent.windowsKeyCode = windowsKeyCodeForKeyEvent(ev->key(), ev->modifiers() & Qt::KeypadModifier); - webKitEvent.setKeyIdentifierFromWindowsKeyCode(); webKitEvent.domKey = getDomKeyFromQKeyEvent(ev); ui::DomCode domCode = ui::DomCode::NONE; |