diff options
Diffstat (limited to 'src/core')
93 files changed, 1754 insertions, 1247 deletions
diff --git a/src/core/api/qtwebenginecoreglobal.cpp b/src/core/api/qtwebenginecoreglobal.cpp index 072f27967..0353dac7d 100644 --- a/src/core/api/qtwebenginecoreglobal.cpp +++ b/src/core/api/qtwebenginecoreglobal.cpp @@ -85,11 +85,9 @@ QWEBENGINE_PRIVATE_EXPORT void initialize() return; } -#if (QT_VERSION >= QT_VERSION_CHECK(5, 6, 1)) // Bail out silently if the user did not construct a QGuiApplication. if (!qobject_cast<QGuiApplication *>(app)) return; -#endif if (app->thread() != QThread::currentThread()) { qFatal("QtWebEngine::initialize() must be called from the Qt gui thread."); diff --git a/src/core/api/qwebenginecallback.h b/src/core/api/qwebenginecallback.h index b967f926a..b981b2afb 100644 --- a/src/core/api/qwebenginecallback.h +++ b/src/core/api/qwebenginecallback.h @@ -92,11 +92,9 @@ private: Q_DECLARE_SHARED(QWebEngineCallback<int>) Q_DECLARE_SHARED(QWebEngineCallback<const QByteArray &>) -#if QT_VERSION >= QT_VERSION_CHECK(5,6,0) Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QWebEngineCallback<bool>) Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QWebEngineCallback<const QString &>) Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QWebEngineCallback<const QVariant &>) -#endif QT_END_NAMESPACE diff --git a/src/core/api/qwebenginecallback_p.h b/src/core/api/qwebenginecallback_p.h index b88ef4d2c..fdaf84d21 100644 --- a/src/core/api/qwebenginecallback_p.h +++ b/src/core/api/qwebenginecallback_p.h @@ -242,12 +242,10 @@ void CallbackDirectory::CallbackSharedDataPointer<T>::invokeEmpty() parent->invokeEmptyInternal(callback); } -#if QT_VERSION >= QT_VERSION_CHECK(5,6,0) #define CHECK_RELOCATABLE(x) \ Q_STATIC_ASSERT((QTypeInfoQuery<QWebEngineCallback< x > >::isRelocatable)); FOR_EACH_TYPE(CHECK_RELOCATABLE) #undef CHECK_RELOCATABLE -#endif } // namespace QtWebEngineCore diff --git a/src/core/api/qwebengineurlrequestjob.cpp b/src/core/api/qwebengineurlrequestjob.cpp index 1db23f6ab..a071adbd5 100644 --- a/src/core/api/qwebengineurlrequestjob.cpp +++ b/src/core/api/qwebengineurlrequestjob.cpp @@ -39,6 +39,7 @@ #include "qwebengineurlrequestjob.h" +#include "url_request_custom_job_proxy.h" #include "url_request_custom_job_delegate.h" using QtWebEngineCore::URLRequestCustomJobDelegate; @@ -114,10 +115,16 @@ QByteArray QWebEngineUrlRequestJob::requestMethod() const /*! Replies to the request with \a device and the MIME type \a contentType. + The user has to be aware that \a device will be used on another thread + until the job is deleted. In case simultaneous access from the main thread + is desired, the user is reponsible for making access to \a device thread-safe + for example by using QMutex. Note that the \a device object is not owned by + the web engine. Therefore, the signal QObject::destroyed() of + QWebEngineUrlRequestJob must be monitored. */ void QWebEngineUrlRequestJob::reply(const QByteArray &contentType, QIODevice *device) { - d_ptr->setReply(contentType, device); + d_ptr->reply(contentType, device); } /*! diff --git a/src/core/api/qwebengineurlrequestjob.h b/src/core/api/qwebengineurlrequestjob.h index afa542d7e..4f23ab401 100644 --- a/src/core/api/qwebengineurlrequestjob.h +++ b/src/core/api/qwebengineurlrequestjob.h @@ -48,7 +48,7 @@ namespace QtWebEngineCore { class URLRequestCustomJobDelegate; -class URLRequestCustomJobShared; +class URLRequestCustomJobProxy; } // namespace QT_BEGIN_NAMESPACE @@ -79,7 +79,7 @@ public: private: QWebEngineUrlRequestJob(QtWebEngineCore::URLRequestCustomJobDelegate *); - friend class QtWebEngineCore::URLRequestCustomJobShared; + friend class QtWebEngineCore::URLRequestCustomJobProxy; QtWebEngineCore::URLRequestCustomJobDelegate* d_ptr; }; diff --git a/src/core/browser_accessibility_qt.cpp b/src/core/browser_accessibility_qt.cpp index 8d82f10e7..9d9ae9009 100644 --- a/src/core/browser_accessibility_qt.cpp +++ b/src/core/browser_accessibility_qt.cpp @@ -127,7 +127,7 @@ void *BrowserAccessibilityQt::interface_cast(QAccessible::InterfaceType type) QAccessibleInterface *BrowserAccessibilityQt::parent() const { - BrowserAccessibility *p = GetParent(); + BrowserAccessibility *p = PlatformGetParent(); if (p) return static_cast<BrowserAccessibilityQt*>(p); return static_cast<BrowserAccessibilityManagerQt*>(manager())->rootParentAccessible(); @@ -182,17 +182,21 @@ QRect BrowserAccessibilityQt::rect() const QAccessible::Role BrowserAccessibilityQt::role() const { switch (GetRole()) { + case ui::AX_ROLE_NONE: case ui::AX_ROLE_UNKNOWN: return QAccessible::NoRole; // Used by Chromium to distinguish between the root of the tree // for this page, and a web area for a frame within this page. case ui::AX_ROLE_WEB_AREA: + case ui::AX_ROLE_WEB_VIEW: case ui::AX_ROLE_ROOT_WEB_AREA: // not sure if we need to make a diff here, but this seems common return QAccessible::WebDocument; // These roles all directly correspond to blink accessibility roles, // keep these alphabetical. + case ui::AX_ROLE_ABBR: + return QAccessible::StaticText; case ui::AX_ROLE_ALERT: case ui::AX_ROLE_ALERT_DIALOG: return QAccessible::AlertMessage; @@ -202,18 +206,22 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::Document; // returning Application here makes Qt return the top level app object case ui::AX_ROLE_ARTICLE: return QAccessible::Section; + case ui::AX_ROLE_AUDIO: + return QAccessible::Sound; case ui::AX_ROLE_BANNER: return QAccessible::Section; case ui::AX_ROLE_BLOCKQUOTE: return QAccessible::Section; case ui::AX_ROLE_BUSY_INDICATOR: - return QAccessible::Animation; // FIXME + return QAccessible::NoRole; // This is unused and planned to be removed. case ui::AX_ROLE_BUTTON: return QAccessible::Button; case ui::AX_ROLE_BUTTON_DROP_DOWN: - return QAccessible::Button; + return QAccessible::ButtonDropDown; case ui::AX_ROLE_CANVAS: return QAccessible::Canvas; + case ui::AX_ROLE_CAPTION: + return QAccessible::Heading; case ui::AX_ROLE_CELL: return QAccessible::Cell; case ui::AX_ROLE_CHECK_BOX: @@ -232,10 +240,17 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::ComplementaryContent; case ui::AX_ROLE_CONTENT_INFO: return QAccessible::Section; + case ui::AX_ROLE_DATE: + case ui::AX_ROLE_DATE_TIME: + return QAccessible::Clock; case ui::AX_ROLE_DEFINITION: return QAccessible::Paragraph; + case ui::AX_ROLE_DESCRIPTION_LIST: + return QAccessible::List; case ui::AX_ROLE_DESCRIPTION_LIST_DETAIL: return QAccessible::Paragraph; + case ui::AX_ROLE_DETAILS: + return QAccessible::Grouping; case ui::AX_ROLE_DESCRIPTION_LIST_TERM: return QAccessible::ListItem; case ui::AX_ROLE_DESKTOP: @@ -246,12 +261,18 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::NoRole; // FIXME case ui::AX_ROLE_DISCLOSURE_TRIANGLE: return QAccessible::NoRole; // FIXME - case ui::AX_ROLE_DIV: + case ui::AX_ROLE_GENERIC_CONTAINER: return QAccessible::Section; case ui::AX_ROLE_DOCUMENT: return QAccessible::Document; case ui::AX_ROLE_EMBEDDED_OBJECT: return QAccessible::Grouping; // FIXME + case ui::AX_ROLE_FEED: + return QAccessible::Section; + case ui::AX_ROLE_FIGCAPTION: + return QAccessible::Heading; + case ui::AX_ROLE_FIGURE: + return QAccessible::Section; case ui::AX_ROLE_FOOTER: return QAccessible::Footer; case ui::AX_ROLE_FORM: @@ -264,6 +285,8 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::Heading; case ui::AX_ROLE_IFRAME: return QAccessible::Grouping; + case ui::AX_ROLE_IFRAME_PRESENTATIONAL: + return QAccessible::NoRole; // FIXME case ui::AX_ROLE_IGNORED: return QAccessible::NoRole; case ui::AX_ROLE_IMAGE: @@ -274,16 +297,20 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::Link; case ui::AX_ROLE_INLINE_TEXT_BOX: return QAccessible::EditableText; + case ui::AX_ROLE_INPUT_TIME: + return QAccessible::SpinBox; case ui::AX_ROLE_LABEL_TEXT: return QAccessible::StaticText; case ui::AX_ROLE_LEGEND: - return QAccessible::NoRole; // FIXME + return QAccessible::StaticText; + case ui::AX_ROLE_LINE_BREAK: + return QAccessible::Separator; case ui::AX_ROLE_LINK: return QAccessible::Link; case ui::AX_ROLE_LIST: return QAccessible::List; case ui::AX_ROLE_LIST_BOX: - return QAccessible::List; + return QAccessible::ComboBox; case ui::AX_ROLE_LIST_BOX_OPTION: return QAccessible::ListItem; case ui::AX_ROLE_LIST_ITEM: @@ -293,11 +320,13 @@ QAccessible::Role BrowserAccessibilityQt::role() const case ui::AX_ROLE_LOCATION_BAR: return QAccessible::NoRole; // FIXME case ui::AX_ROLE_LOG: - return QAccessible::NoRole; // FIXME + return QAccessible::Section; case ui::AX_ROLE_MAIN: - return QAccessible::NoRole; // FIXME + return QAccessible::Grouping; + case ui::AX_ROLE_MARK: + return QAccessible::StaticText; case ui::AX_ROLE_MARQUEE: - return QAccessible::NoRole; // FIXME + return QAccessible::Section; case ui::AX_ROLE_MATH: return QAccessible::Equation; case ui::AX_ROLE_MENU: @@ -306,12 +335,18 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::MenuBar; case ui::AX_ROLE_MENU_ITEM: return QAccessible::MenuItem; + case ui::AX_ROLE_MENU_ITEM_CHECK_BOX: + return QAccessible::CheckBox; + case ui::AX_ROLE_MENU_ITEM_RADIO: + return QAccessible::RadioButton; case ui::AX_ROLE_MENU_BUTTON: return QAccessible::MenuItem; case ui::AX_ROLE_MENU_LIST_OPTION: return QAccessible::MenuItem; case ui::AX_ROLE_MENU_LIST_POPUP: return QAccessible::PopupMenu; + case ui::AX_ROLE_METER: + return QAccessible::Chart; case ui::AX_ROLE_NAVIGATION: return QAccessible::Section; case ui::AX_ROLE_NOTE: @@ -340,6 +375,8 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::Row; case ui::AX_ROLE_ROW_HEADER: return QAccessible::RowHeader; + case ui::AX_ROLE_RUBY: + return QAccessible::StaticText; case ui::AX_ROLE_RULER: return QAccessible::NoRole; // FIXME case ui::AX_ROLE_SCROLL_AREA: @@ -350,6 +387,8 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::NoRole; // FIXME case ui::AX_ROLE_SEARCH: return QAccessible::Section; + case ui::AX_ROLE_SEARCH_BOX: + return QAccessible::EditableText; case ui::AX_ROLE_SLIDER: return QAccessible::Slider; case ui::AX_ROLE_SLIDER_THUMB: @@ -363,9 +402,11 @@ QAccessible::Role BrowserAccessibilityQt::role() const case ui::AX_ROLE_STATIC_TEXT: return QAccessible::StaticText; case ui::AX_ROLE_STATUS: - return QAccessible::StatusBar; + return QAccessible::Indicator; case ui::AX_ROLE_SVG_ROOT: return QAccessible::Graphic; + case ui::AX_ROLE_SWITCH: + return QAccessible::Button; case ui::AX_ROLE_TABLE: return QAccessible::Table; case ui::AX_ROLE_TABLE_HEADER_CONTAINER: @@ -378,8 +419,11 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::PageTabList; case ui::AX_ROLE_TAB_PANEL: return QAccessible::PageTab; + case ui::AX_ROLE_TERM: + return QAccessible::StaticText; case ui::AX_ROLE_TEXT_FIELD: return QAccessible::EditableText; + case ui::AX_ROLE_TIME: case ui::AX_ROLE_TIMER: return QAccessible::Clock; case ui::AX_ROLE_TITLE_BAR: @@ -396,6 +440,8 @@ QAccessible::Role BrowserAccessibilityQt::role() const return QAccessible::Tree; case ui::AX_ROLE_TREE_ITEM: return QAccessible::TreeItem; + case ui::AX_ROLE_VIDEO: + return QAccessible::Animation; case ui::AX_ROLE_WINDOW: return QAccessible::Window; } @@ -408,7 +454,7 @@ QAccessible::State BrowserAccessibilityQt::state() const int32_t s = GetState(); if (s & (1 << ui::AX_STATE_BUSY)) state.busy = true; - if (s & (1 << ui::AX_STATE_CHECKED)) + if (s & (1 << ui::AX_CHECKED_STATE_TRUE)) state.checked = true; if (s & (1 << ui::AX_STATE_COLLAPSED)) state.collapsed = true; @@ -491,7 +537,7 @@ QStringList BrowserAccessibilityQt::keyBindingsForAction(const QString &actionNa void BrowserAccessibilityQt::addSelection(int startOffset, int endOffset) { - manager()->SetTextSelection(*this, startOffset, endOffset); + manager()->SetSelection(AXPlatformRange(CreatePositionAt(startOffset), CreatePositionAt(endOffset))); } QString BrowserAccessibilityQt::attributes(int offset, int *startOffset, int *endOffset) const @@ -549,19 +595,19 @@ QString BrowserAccessibilityQt::text(int startOffset, int endOffset) const void BrowserAccessibilityQt::removeSelection(int selectionIndex) { - manager()->SetTextSelection(*this, 0, 0); + manager()->SetSelection(AXPlatformRange(CreatePositionAt(0), CreatePositionAt(0))); } void BrowserAccessibilityQt::setCursorPosition(int position) { - manager()->SetTextSelection(*this, position, position); + manager()->SetSelection(AXPlatformRange(CreatePositionAt(position), CreatePositionAt(position))); } void BrowserAccessibilityQt::setSelection(int selectionIndex, int startOffset, int endOffset) { if (selectionIndex != 0) return; - manager()->SetTextSelection(*this, startOffset, endOffset); + manager()->SetSelection(AXPlatformRange(CreatePositionAt(startOffset), CreatePositionAt(endOffset))); } int BrowserAccessibilityQt::characterCount() const @@ -784,9 +830,9 @@ bool BrowserAccessibilityQt::isSelected() const QAccessibleInterface *BrowserAccessibilityQt::table() const { - BrowserAccessibility* find_table = GetParent(); + BrowserAccessibility* find_table = PlatformGetParent(); while (find_table && find_table->GetRole() != ui::AX_ROLE_TABLE) - find_table = find_table->GetParent(); + find_table = find_table->PlatformGetParent(); if (!find_table) return 0; return static_cast<BrowserAccessibilityQt*>(find_table); diff --git a/src/core/browser_context_adapter.cpp b/src/core/browser_context_adapter.cpp index bec76ad81..f76969c74 100644 --- a/src/core/browser_context_adapter.cpp +++ b/src/core/browser_context_adapter.cpp @@ -184,6 +184,16 @@ void BrowserContextAdapter::cancelDownload(quint32 downloadId) downloadManagerDelegate()->cancelDownload(downloadId); } +void BrowserContextAdapter::pauseDownload(quint32 downloadId) +{ + downloadManagerDelegate()->pauseDownload(downloadId); +} + +void BrowserContextAdapter::resumeDownload(quint32 downloadId) +{ + downloadManagerDelegate()->resumeDownload(downloadId); +} + QSharedPointer<BrowserContextAdapter> BrowserContextAdapter::defaultContext() { return WebEngineContext::current()->defaultBrowserContext(); diff --git a/src/core/browser_context_adapter.h b/src/core/browser_context_adapter.h index f6ebfd51c..5960014b9 100644 --- a/src/core/browser_context_adapter.h +++ b/src/core/browser_context_adapter.h @@ -86,6 +86,8 @@ public: void removeClient(BrowserContextAdapterClient *adapterClient); void cancelDownload(quint32 downloadId); + void pauseDownload(quint32 downloadId); + void resumeDownload(quint32 downloadId); BrowserContextQt *browserContext(); diff --git a/src/core/browser_context_adapter_client.h b/src/core/browser_context_adapter_client.h index e1fd02f96..02bee8ed6 100644 --- a/src/core/browser_context_adapter_client.h +++ b/src/core/browser_context_adapter_client.h @@ -118,6 +118,8 @@ public: QString path; int savePageFormat; bool accepted; + bool paused; + bool done; int downloadType; int downloadInterruptReason; }; diff --git a/src/core/browser_context_qt.cpp b/src/core/browser_context_qt.cpp index ffee001ff..16b7e5514 100644 --- a/src/core/browser_context_qt.cpp +++ b/src/core/browser_context_qt.cpp @@ -57,7 +57,7 @@ #include "base/base_paths.h" #include "components/prefs/pref_member.h" #include "components/prefs/pref_service.h" -#include "components/prefs/testing_pref_store.h" +#include "components/prefs/in_memory_pref_store.h" #include "components/prefs/pref_service.h" #include "components/prefs/pref_service_factory.h" #include "components/prefs/pref_registry_simple.h" @@ -72,9 +72,8 @@ namespace QtWebEngineCore { BrowserContextQt::BrowserContextQt(BrowserContextAdapter *adapter) : m_adapter(adapter), - m_prefStore(new TestingPrefStore()) + m_prefStore(new InMemoryPrefStore()) { - m_prefStore->SetInitializationCompleted(); PrefServiceFactory factory; factory.set_user_prefs(m_prefStore); scoped_refptr<PrefRegistrySimple> registry(new PrefRegistrySimple()); @@ -82,7 +81,7 @@ BrowserContextQt::BrowserContextQt(BrowserContextAdapter *adapter) #if BUILDFLAG(ENABLE_SPELLCHECK) // Initial spellcheck settings registry->RegisterStringPref(prefs::kAcceptLanguages, std::string()); - registry->RegisterListPref(spellcheck::prefs::kSpellCheckDictionaries, new base::ListValue()); + registry->RegisterListPref(spellcheck::prefs::kSpellCheckDictionaries, base::MakeUnique<base::ListValue>()); registry->RegisterStringPref(spellcheck::prefs::kSpellCheckDictionary, std::string()); registry->RegisterBooleanPref(spellcheck::prefs::kEnableSpellcheck, false); registry->RegisterBooleanPref(spellcheck::prefs::kSpellCheckUseSpellingService, false); @@ -206,7 +205,7 @@ net::URLRequestContextGetter *BrowserContextQt::CreateRequestContextForStoragePa } #if BUILDFLAG(ENABLE_SPELLCHECK) -void BrowserContextQt::failedToLoadDictionary(const std::string &language) +void BrowserContextQt::FailedToLoadDictionary(const std::string &language) { Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); qWarning() << "Could not load dictionary for:" << toQt(language) << endl @@ -229,7 +228,7 @@ QStringList BrowserContextQt::spellCheckLanguages() const QStringList spellcheck_dictionaries; for (const auto &value : *m_prefService->GetList(spellcheck::prefs::kSpellCheckDictionaries)) { std::string dictionary; - if (value->GetAsString(&dictionary)) + if (value.GetAsString(&dictionary)) spellcheck_dictionaries.append(QString::fromStdString(dictionary)); } diff --git a/src/core/browser_context_qt.h b/src/core/browser_context_qt.h index af250f506..681657d96 100644 --- a/src/core/browser_context_qt.h +++ b/src/core/browser_context_qt.h @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE class QStringList; QT_END_NAMESPACE -class TestingPrefStore; +class InMemoryPrefStore; class PrefService; namespace QtWebEngineCore { @@ -100,7 +100,7 @@ public: BrowserContextAdapter *adapter() { return m_adapter; } #if BUILDFLAG(ENABLE_SPELLCHECK) - void failedToLoadDictionary(const std::string& language) override; + void FailedToLoadDictionary(const std::string& language) override; void setSpellCheckLanguages(const QStringList &languages); QStringList spellCheckLanguages() const; void setSpellCheckEnabled(bool enabled); @@ -115,7 +115,7 @@ private: std::unique_ptr<PermissionManagerQt> permissionManager; std::unique_ptr<SSLHostStateDelegateQt> sslHostStateDelegate; BrowserContextAdapter *m_adapter; - scoped_refptr<TestingPrefStore> m_prefStore; + scoped_refptr<InMemoryPrefStore> m_prefStore; std::unique_ptr<PrefService> m_prefService; friend class BrowserContextAdapter; diff --git a/src/core/chromium_gpu_helper.cpp b/src/core/chromium_gpu_helper.cpp index 09fe9f39e..483f68aac 100644 --- a/src/core/chromium_gpu_helper.cpp +++ b/src/core/chromium_gpu_helper.cpp @@ -65,13 +65,13 @@ base::MessageLoop *gpu_message_loop() gpu::SyncPointManager *sync_point_manager() { - gpu::GpuChannelManager *gpuChannelManager = content::GpuChildThread::instance()->ChannelManager(); + gpu::GpuChannelManager *gpuChannelManager = content::GpuChildThread::instance()->gpu_channel_manager(); return gpuChannelManager->sync_point_manager(); } gpu::gles2::MailboxManager *mailbox_manager() { - gpu::GpuChannelManager *gpuChannelManager = content::GpuChildThread::instance()->ChannelManager(); + gpu::GpuChannelManager *gpuChannelManager = content::GpuChildThread::instance()->gpu_channel_manager(); return gpuChannelManager->mailbox_manager(); } diff --git a/src/core/chromium_overrides.cpp b/src/core/chromium_overrides.cpp index 9afa80757..9aeeb1327 100644 --- a/src/core/chromium_overrides.cpp +++ b/src/core/chromium_overrides.cpp @@ -49,6 +49,7 @@ #include "content/common/font_list.h" #include "ui/base/dragdrop/os_exchange_data.h" #include "ui/base/dragdrop/os_exchange_data_provider_factory.h" +#include "ppapi/features/features.h" #include <QGuiApplication> #include <QScreen> @@ -141,7 +142,7 @@ std::unique_ptr<base::ListValue> GetFontList_SlowBlocking() return std::move(font_list); } -#if defined(ENABLE_PLUGINS) +#if BUILDFLAG(ENABLE_PLUGINS) // content/browser/renderer_host/pepper/pepper_truetype_font_list.h void GetFontFamilies_SlowBlocking(std::vector<std::string> *font_families) { @@ -155,7 +156,7 @@ void GetFontsInFamily_SlowBlocking(const std::string &, std::vector<ppapi::proxy { QT_NOT_USED } -#endif //defined(ENABLE_PLUGINS) +#endif // BUILDFLAG(ENABLE_PLUGINS) } // namespace content @@ -170,7 +171,7 @@ ui::OSExchangeDataProviderFactory::CreateProvider() { #if defined(USE_OPENSSL_CERTS) namespace net { -scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey(X509Certificate* certificate) +scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey(const X509Certificate* certificate) { return OpenSSLClientKeyStore::GetInstance()->FetchClientCertPrivateKey(certificate); } diff --git a/src/core/clipboard_qt.cpp b/src/core/clipboard_qt.cpp index 7bf53add5..152c4db63 100644 --- a/src/core/clipboard_qt.cpp +++ b/src/core/clipboard_qt.cpp @@ -352,13 +352,20 @@ SkBitmap ClipboardQt::ReadImage(ui::ClipboardType type) const image = image.convertToFormat(QImage::Format_ARGB32); SkBitmap bitmap; - bitmap.setInfo(SkImageInfo::MakeN32(image.width(), image.height(), kOpaque_SkAlphaType)); - bitmap.setPixels(const_cast<uchar*>(image.constBits())); - // Return a deep copy of the pixel data. - SkBitmap copy; - bitmap.copyTo(©, kN32_SkColorType); - return copy; + bitmap.allocN32Pixels(image.width(), image.height(), true); + const size_t bytesPerRowDst = bitmap.rowBytes(); + const size_t bytesPerLineSrc = static_cast<size_t>(image.bytesPerLine()); + const size_t dataBytes = std::min(bytesPerRowDst, bytesPerLineSrc); + uchar *dst = static_cast<uchar *>(bitmap.getPixels()); + const uchar *src = image.constBits(); + for (int y = 0; y < image.height(); ++y) { + memcpy(dst, src, dataBytes); + dst += bytesPerRowDst; + src += bytesPerLineSrc; + } + + return bitmap; } void ClipboardQt::ReadCustomData(ui::ClipboardType clipboard_type, const base::string16& type, base::string16* result) const diff --git a/src/core/clipboard_qt.h b/src/core/clipboard_qt.h index c2ced4941..20b51a599 100644 --- a/src/core/clipboard_qt.h +++ b/src/core/clipboard_qt.h @@ -82,6 +82,8 @@ public: void ReadBookmark(base::string16* title, std::string* url) const override; void ReadData(const FormatType& format, std::string* result) const override; + virtual void OnPreShutdown() Q_DECL_OVERRIDE { } + protected: void WriteObjects(ui::ClipboardType type, const ObjectMap& objects) override; void WriteText(const char* text_data, size_t text_len) override; diff --git a/src/core/common/qt_messages.h b/src/core/common/qt_messages.h index 239122e3f..fae80186b 100644 --- a/src/core/common/qt_messages.h +++ b/src/core/common/qt_messages.h @@ -43,11 +43,11 @@ IPC_MESSAGE_ROUTED1(WebChannelIPCTransport_Uninstall, uint /* worldId */) IPC_MESSAGE_ROUTED2(WebChannelIPCTransport_Message, std::vector<char> /*binaryJSON*/, uint /* worldId */) // User scripts messages -IPC_MESSAGE_ROUTED1(RenderViewObserverHelper_AddScript, +IPC_MESSAGE_ROUTED1(RenderFrameObserverHelper_AddScript, UserScriptData /* script */) -IPC_MESSAGE_ROUTED1(RenderViewObserverHelper_RemoveScript, +IPC_MESSAGE_ROUTED1(RenderFrameObserverHelper_RemoveScript, UserScriptData /* script */) -IPC_MESSAGE_ROUTED0(RenderViewObserverHelper_ClearScripts) +IPC_MESSAGE_ROUTED0(RenderFrameObserverHelper_ClearScripts) IPC_MESSAGE_CONTROL1(UserResourceController_AddScript, UserScriptData /* scriptContents */) IPC_MESSAGE_CONTROL1(UserResourceController_RemoveScript, UserScriptData /* scriptContents */) diff --git a/src/core/config/common.pri b/src/core/config/common.pri index b0723e333..2aa3c614d 100644 --- a/src/core/config/common.pri +++ b/src/core/config/common.pri @@ -4,46 +4,42 @@ 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_shim=false \ use_allocator=\"none\" \ v8_use_external_startup_data=false \ - treat_warnings_as_errors=false + treat_warnings_as_errors=false \ + enable_swiftshader=false -use?(printing) { +qtConfig(printing-and-pdf) { 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_basic_printing=false enable_print_preview=false gn_args += enable_pdf=false } -use?(pepper_plugins) { +qtConfig(pepper-plugins) { gn_args += enable_plugins=true enable_widevine=true } else { gn_args += enable_plugins=false enable_widevine=false } -use?(spellchecker) { +qtConfig(spellchecker) { gn_args += enable_spellcheck=true } else { gn_args += enable_spellcheck=false } -use?(webrtc) { +qtConfig(webrtc) { gn_args += enable_webrtc=true } else { gn_args += enable_webrtc=false } -use?(proprietary_codecs): gn_args += proprietary_codecs=true ffmpeg_branding=\"Chrome\" +qtConfig(proprietary-codecs): gn_args += proprietary_codecs=true ffmpeg_branding=\"Chrome\" CONFIG(release, debug|release) { force_debug_info { @@ -55,8 +51,12 @@ CONFIG(release, debug|release) { } } +CONFIG(debug, debug|release) { + gn_args += use_debug_fission=false +} + !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 +optimize_size: gn_args += optimize_for_size=true diff --git a/src/core/config/desktop_linux.pri b/src/core/config/desktop_linux.pri index 9918e1bb2..70f1cf81e 100644 --- a/src/core/config/desktop_linux.pri +++ b/src/core/config/desktop_linux.pri @@ -3,11 +3,6 @@ include(linux.pri) 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 diff --git a/src/core/config/embedded_linux.pri b/src/core/config/embedded_linux.pri index d5f6d4bf5..8d9f09deb 100644 --- a/src/core/config/embedded_linux.pri +++ b/src/core/config/embedded_linux.pri @@ -6,13 +6,8 @@ gn_args += \ use_ozone=true \ use_sysroot=false \ enable_session_service=false \ - enable_notifications=false \ ozone_auto_platforms=false \ ozone_platform_headless=true \ ozone_platform_external=true \ ozone_platform=\"qt\" \ toolkit_views=false - -use?(icecc) { - gn_args += use_debug_fission=false -} diff --git a/src/core/config/linux.pri b/src/core/config/linux.pri index 831e1952c..78f3e5093 100644 --- a/src/core/config/linux.pri +++ b/src/core/config/linux.pri @@ -8,17 +8,10 @@ gn_args += \ use_gio=false \ use_gnome_keyring=false \ use_kerberos=false \ - linux_use_bundled_binutils=false + linux_use_bundled_binutils=false \ + use_nss_certs=true \ + use_openssl_certs=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 { @@ -119,13 +112,17 @@ host_build { # Strip '>2 /dev/null' from $$pkgConfigExecutable() PKGCONFIG = $$first($$list($$pkgConfigExecutable())) gn_args += pkg_config=\"$$PKGCONFIG\" + gn_args += host_pkg_config=\"pkg-config\" } - 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(webengine-system-zlib): qtConfig(system-minizip) { + gn_args += use_system_zlib=true use_system_minizip=true + } + qtConfig(webengine-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(system-freetype): gn_args += use_system_freetype=true + qtConfig(webengine-system-harfbuzz): gn_args += use_system_harfbuzz=true + qtConfig(system-glib): gn_args += use_glib=false qtConfig(pulseaudio) { gn_args += use_pulseaudio=true } else { @@ -141,15 +138,18 @@ host_build { !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_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_re2): gn_args += use_system_re2=true - #use?(system_protobuf): gn_args += use_system_protobuf=true + qtConfig(system-libevent): gn_args += use_system_libevent=true + qtConfig(system-libwebp): gn_args += use_system_libwebp=true + qtConfig(system-libxml2): gn_args += use_system_libxml=true use_system_libxslt=true + qtConfig(system-opus): gn_args += use_system_opus=true + qtConfig(system-snappy): gn_args += use_system_snappy=true + qtConfig(system-libvpx): gn_args += use_system_libvpx=true + qtConfig(system-icu): gn_args += use_system_icu=true icu_use_data_file=false + qtConfig(system-ffmpeg): gn_args += use_system_ffmpeg=true + qtConfig(system-re2): gn_args += use_system_re2=true + + # FIXME: + #qtConfig(system-protobuf): gn_args += use_system_protobuf=true + #qtConfig(system-jsoncpp): gn_args += use_system_jsoncpp=true + #qtConfig(system-libsrtp: gn_args += use_system_libsrtp=true } diff --git a/src/core/config/mac_osx.pri b/src/core/config/mac_osx.pri index ddb397565..57f301f18 100644 --- a/src/core/config/mac_osx.pri +++ b/src/core/config/mac_osx.pri @@ -32,9 +32,9 @@ gn_args += \ toolkit_views=false \ use_external_popup_menu=false -use?(spellchecker) { - use?(native_spellchecker): gn_args += use_browser_spellchecker=true +qtConfig(spellchecker) { + qtConfig(native-spellchecker): gn_args += use_browser_spellchecker=true else: gn_args += use_browser_spellchecker=false } else { - macos: gn_args += use_browser_spellchecker=false + gn_args += use_browser_spellchecker=false } diff --git a/src/core/config/windows.pri b/src/core/config/windows.pri index db1fbd3d7..f74e0bb85 100644 --- a/src/core/config/windows.pri +++ b/src/core/config/windows.pri @@ -4,7 +4,6 @@ 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 \ @@ -12,10 +11,20 @@ gn_args += \ isDeveloperBuild() { gn_args += \ - is_win_fastlink=true \ - use_incremental_linking=true + is_win_fastlink=true + + # Incremental linking doesn't work in release developer builds due to usage of /OPT:ICF + # by Chromium. + CONFIG(debug, debug|release) { + gn_args += \ + use_incremental_linking=true + } else { + gn_args += \ + use_incremental_linking=false + } } else { gn_args += \ + is_win_fastlink=false \ use_incremental_linking=false } diff --git a/src/core/content_browser_client_qt.cpp b/src/core/content_browser_client_qt.cpp index d446d8ff4..97d3ad6bb 100644 --- a/src/core/content_browser_client_qt.cpp +++ b/src/core/content_browser_client_qt.cpp @@ -46,7 +46,7 @@ #if BUILDFLAG(ENABLE_SPELLCHECK) #include "chrome/browser/spellchecker/spellcheck_message_filter.h" #if BUILDFLAG(USE_BROWSER_SPELLCHECKER) -#include "chrome/browser/spellchecker/spellcheck_message_filter_platform.h" +#include "components/spellcheck/browser/spellcheck_message_filter_platform.h" #endif #endif #include "content/browser/renderer_host/render_view_host_delegate.h" @@ -59,6 +59,7 @@ #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/resource_dispatcher_host.h" +#include "content/public/browser/storage_partition.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_user_data.h" #include "content/public/common/content_switches.h" @@ -68,7 +69,8 @@ #include "device/geolocation/geolocation_provider.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/binding_set.h" -#include "services/service_manager/public/cpp/interface_registry.h" +#include "services/service_manager/public/cpp/bind_source_info.h" +#include "services/service_manager/public/cpp/binder_registry.h" #include "third_party/WebKit/public/platform/modules/sensitive_input_visibility/sensitive_input_visibility_service.mojom.h" #include "ui/base/ui_base_switches.h" #include "ui/display/screen.h" @@ -107,7 +109,7 @@ #include "ui/base/resource/resource_bundle.h" #endif -#if defined(ENABLE_PLUGINS) +#if BUILDFLAG(ENABLE_PLUGINS) #include "content/public/browser/browser_ppapi_host.h" #include "ppapi/host/ppapi_host.h" #include "renderer_host/pepper/pepper_host_factory_qt.h" @@ -459,6 +461,17 @@ content::QuotaPermissionContext *ContentBrowserClientQt::CreateQuotaPermissionCo return new QuotaPermissionContextQt; } +void ContentBrowserClientQt::GetQuotaSettings(content::BrowserContext *context, + content::StoragePartition *partition, + const storage::OptionalQuotaSettingsCallback &callback) +{ + content::BrowserThread::PostTaskAndReplyWithResult( + content::BrowserThread::FILE, FROM_HERE, + base::Bind(&storage::CalculateNominalDynamicSettings, + partition->GetPath(), context->IsOffTheRecord()), + callback); +} + void ContentBrowserClientQt::AllowCertificateError(content::WebContents *webContents, int cert_error, const net::SSLInfo& ssl_info, @@ -477,6 +490,7 @@ void ContentBrowserClientQt::AllowCertificateError(content::WebContents *webCont void ContentBrowserClientQt::SelectClientCertificate(content::WebContents * /*webContents*/, net::SSLCertRequestInfo * /*certRequestInfo*/, + net::CertificateList /*client_certs*/, std::unique_ptr<content::ClientCertificateDelegate> delegate) { delegate->ContinueWithCertificate(nullptr); @@ -522,7 +536,7 @@ void ContentBrowserClientQt::GetAdditionalMappedFilesForChildProcess(const base: } #endif -#if defined(ENABLE_PLUGINS) +#if BUILDFLAG(ENABLE_PLUGINS) void ContentBrowserClientQt::DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) { browser_host->GetPpapiHost()->AddHostFactoryFilter( @@ -557,6 +571,7 @@ public: return FromWebContents(web_contents); } static void BindSensitiveInputVisibilityService(content::RenderFrameHost* render_frame_host, + const service_manager::BindSourceInfo& source_info, blink::mojom::SensitiveInputVisibilityServiceRequest request) { CreateForRenderFrameHost(render_frame_host); @@ -583,12 +598,54 @@ private: }; -void ContentBrowserClientQt::RegisterRenderFrameMojoInterfaces(service_manager::InterfaceRegistry* registry, - content::RenderFrameHost* render_frame_host) +void ContentBrowserClientQt::ExposeInterfacesToFrame(service_manager::BinderRegistry* registry, + content::RenderFrameHost* render_frame_host) { registry->AddInterface(base::Bind(&ServiceDriver::BindSensitiveInputVisibilityService, render_frame_host)); } +bool ContentBrowserClientQt::CanCreateWindow( + content::RenderFrameHost* opener, + const GURL& opener_url, + const GURL& opener_top_level_frame_url, + const GURL& source_origin, + content::mojom::WindowContainerType container_type, + const GURL& target_url, + const content::Referrer& referrer, + const std::string& frame_name, + WindowOpenDisposition disposition, + const blink::mojom::WindowFeatures& features, + bool user_gesture, + bool opener_suppressed, + bool* no_javascript_access) { + + Q_UNUSED(opener_url); + Q_UNUSED(opener_top_level_frame_url); + Q_UNUSED(source_origin); + Q_UNUSED(container_type); + Q_UNUSED(target_url); + Q_UNUSED(referrer); + Q_UNUSED(frame_name); + Q_UNUSED(disposition); + Q_UNUSED(features); + Q_UNUSED(opener_suppressed); + + if (no_javascript_access) + *no_javascript_access = false; + + content::WebContents* webContents = content::WebContents::FromRenderFrameHost(opener); + + WebEngineSettings *settings = nullptr; + if (webContents) { + WebContentsDelegateQt* delegate = + static_cast<WebContentsDelegateQt*>(webContents->GetDelegate()); + if (delegate) + settings = delegate->webEngineSettings(); + } + + return (settings && settings->getJavaScriptCanOpenWindowsAutomatically()) || user_gesture; +} + } // namespace QtWebEngineCore DEFINE_WEB_CONTENTS_USER_DATA_KEY(QtWebEngineCore::ServiceDriver); diff --git a/src/core/content_browser_client_qt.h b/src/core/content_browser_client_qt.h index b17dd3e39..eab8e42ab 100644 --- a/src/core/content_browser_client_qt.h +++ b/src/core/content_browser_client_qt.h @@ -42,6 +42,7 @@ #include "base/memory/ref_counted.h" #include "content/public/browser/content_browser_client.h" +#include "ppapi/features/features.h" #include <QtGlobal> @@ -53,7 +54,7 @@ namespace content { class BrowserContext; class BrowserMainParts; -#if defined(ENABLE_PLUGINS) +#if BUILDFLAG(ENABLE_PLUGINS) class BrowserPpapiHost; #endif @@ -65,6 +66,7 @@ class ResourceContext; class WebContentsViewPort; class WebContents; struct MainFunctionParams; +struct Referrer; } namespace gl { @@ -72,7 +74,7 @@ class GLShareGroup; } namespace service_manager { -class InterfaceRegistry; +class BinderRegistry; } namespace QtWebEngineCore { @@ -93,6 +95,9 @@ public: gl::GLShareGroup* GetInProcessGpuShareGroup() override; content::MediaObserver* GetMediaObserver() override; content::QuotaPermissionContext *CreateQuotaPermissionContext() override; + void GetQuotaSettings(content::BrowserContext *context, + content::StoragePartition *partition, + const storage::OptionalQuotaSettingsCallback &callback) override; void OverrideWebkitPrefs(content::RenderViewHost *, content::WebPreferences *) override; void AllowCertificateError(content::WebContents* web_contents, int cert_error, @@ -105,6 +110,7 @@ public: const base::Callback<void(content::CertificateRequestResultType)>& callback) override; void SelectClientCertificate(content::WebContents* web_contents, net::SSLCertRequestInfo* cert_request_info, + net::CertificateList client_certs, std::unique_ptr<content::ClientCertificateDelegate> delegate) override; content::DevToolsManagerDelegate *GetDevToolsManagerDelegate() override; @@ -113,13 +119,28 @@ public: void AppendExtraCommandLineSwitches(base::CommandLine* command_line, int child_process_id) override; void GetAdditionalWebUISchemes(std::vector<std::string>* additional_schemes) override; - void RegisterRenderFrameMojoInterfaces(service_manager::InterfaceRegistry* registry, content::RenderFrameHost* render_frame_host) override; + void ExposeInterfacesToFrame(service_manager::BinderRegistry* registry, content::RenderFrameHost* render_frame_host) override; + + bool CanCreateWindow( + content::RenderFrameHost* opener, + const GURL& opener_url, + const GURL& opener_top_level_frame_url, + const GURL& source_origin, + content::mojom::WindowContainerType container_type, + const GURL& target_url, + const content::Referrer& referrer, + const std::string& frame_name, + WindowOpenDisposition disposition, + const blink::mojom::WindowFeatures& features, + bool user_gesture, + bool opener_suppressed, + bool* no_javascript_access) override; #if defined(Q_OS_LINUX) void GetAdditionalMappedFilesForChildProcess(const base::CommandLine& command_line, int child_process_id, content::FileDescriptorInfo* mappings) override; #endif -#if defined(ENABLE_PLUGINS) +#if BUILDFLAG(ENABLE_PLUGINS) void DidCreatePpapiPlugin(content::BrowserPpapiHost* browser_host) override; #endif diff --git a/src/core/content_client_qt.cpp b/src/core/content_client_qt.cpp index 3d87cfd45..1016db0d5 100644 --- a/src/core/content_client_qt.cpp +++ b/src/core/content_client_qt.cpp @@ -50,6 +50,8 @@ #include "ui/base/layout.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" + +#include "qrc_protocol_handler_qt.h" #include "type_conversion.h" #include <QCoreApplication> @@ -69,7 +71,7 @@ static QString getLocalAppDataDir() } #endif -#if defined(ENABLE_PLUGINS) +#if BUILDFLAG(ENABLE_PLUGINS) // The plugin logic is based on chrome/common/chrome_content_client.cc: // Copyright (c) 2012 The Chromium Authors. All rights reserved. @@ -284,7 +286,7 @@ void ContentClientQt::AddPepperPlugins(std::vector<content::PepperPluginInfo>* p } } -#endif +#endif // BUILDFLAG(ENABLE_PLUGINS) #include <QCoreApplication> @@ -316,4 +318,9 @@ std::string ContentClientQt::GetProduct() const return productName.toStdString(); } +void ContentClientQt::AddAdditionalSchemes(Schemes* schemes) +{ + schemes->secure_schemes.push_back(kQrcSchemeQt); +} + } // namespace QtWebEngineCore diff --git a/src/core/content_client_qt.h b/src/core/content_client_qt.h index 7104b98b6..341406380 100644 --- a/src/core/content_client_qt.h +++ b/src/core/content_client_qt.h @@ -42,6 +42,7 @@ #include "base/strings/string_piece.h" #include "content/public/common/content_client.h" +#include "ppapi/features/features.h" #include "ui/base/layout.h" namespace QtWebEngineCore { @@ -50,9 +51,10 @@ class ContentClientQt : public content::ContentClient { public: static std::string getUserAgent(); -#if defined(ENABLE_PLUGINS) +#if BUILDFLAG(ENABLE_PLUGINS) void AddPepperPlugins(std::vector<content::PepperPluginInfo>* plugins) override; #endif + void AddAdditionalSchemes(Schemes* schemes) override; base::StringPiece GetDataResource(int, ui::ScaleFactor) const override; base::RefCountedMemory* GetDataResourceBytes(int resource_id) const override; diff --git a/src/core/core_chromium.pri b/src/core/core_chromium.pri index f13095bfe..71f74f51a 100644 --- a/src/core/core_chromium.pri +++ b/src/core/core_chromium.pri @@ -28,7 +28,7 @@ RCC_DIR = $$OUT_PWD/$$getConfigDir()/.rcc # Assume that we want mobile touch and low-end hardware behaviors # whenever we are cross compiling. -contains(WEBENGINE_CONFIG, embedded_build): DEFINES += QTWEBENGINE_EMBEDDED_SWITCHES +qtConfig(embedded): DEFINES += QTWEBENGINE_EMBEDDED_SWITCHES qtConfig(egl): CONFIG += egl @@ -96,6 +96,7 @@ SOURCES = \ url_request_context_getter_qt.cpp \ url_request_custom_job.cpp \ url_request_custom_job_delegate.cpp \ + url_request_custom_job_proxy.cpp \ url_request_qrc_job_qt.cpp \ user_script.cpp \ visited_links_manager_qt.cpp \ @@ -171,6 +172,7 @@ HEADERS = \ url_request_context_getter_qt.h \ url_request_custom_job.h \ url_request_custom_job_delegate.h \ + url_request_custom_job_proxy.h \ url_request_qrc_job_qt.h \ user_script.h \ visited_links_manager_qt.h \ @@ -185,13 +187,8 @@ HEADERS = \ web_engine_settings.h \ web_event_factory.h +qtConfig(pepper-plugins) { -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 \ @@ -207,7 +204,8 @@ use?(pepper_plugins) { renderer/pepper/pepper_renderer_host_factory_qt.h } -use?(printing) { +qtConfig(printing-and-pdf) { + SOURCES += \ printing_message_filter_qt.cpp \ print_view_manager_base_qt.cpp \ @@ -219,6 +217,10 @@ use?(printing) { print_view_manager_base_qt.h \ print_view_manager_qt.h \ renderer/print_web_view_helper_delegate_qt.h + + # pdf sources + SOURCES += pdfium_document_wrapper_qt.cpp + HEADERS += pdfium_document_wrapper_qt.h } contains(QT_CONFIG, opengl) { diff --git a/src/core/core_generator.pro b/src/core/core_generator.pro index 916c211f9..cbf126dda 100644 --- a/src/core/core_generator.pro +++ b/src/core/core_generator.pro @@ -1,3 +1,6 @@ +include($$QTWEBENGINE_OUT_ROOT/qtwebengine-config.pri) +QT_FOR_CONFIG += webengine-private + include(core_gn_config.pri) TEMPLATE = lib diff --git a/src/core/core_module.pro b/src/core/core_module.pro index 3785ddc46..55b20cda2 100644 --- a/src/core/core_module.pro +++ b/src/core/core_module.pro @@ -1,3 +1,6 @@ +include($$QTWEBENGINE_OUT_ROOT/qtwebengine-config.pri) +QT_FOR_CONFIG += webengine-private + MODULE = webenginecore include(core_common.pri) @@ -47,7 +50,17 @@ CONFIG *= no_smart_library_merge osx { LIBS_PRIVATE += -Wl,-force_load,$${api_library_path}$${QMAKE_DIR_SEP}lib$${api_library_name}.a } else:msvc { - QMAKE_LFLAGS += /OPT:REF + !isDeveloperBuild() { + # Remove unused functions and data in debug non-developer builds, because the binaries will + # be smaller in the shipped packages. + QMAKE_LFLAGS += /OPT:REF + } else:CONFIG(debug, debug|release) { + # Make sure to override qtbase's QMAKE_LFLAGS_DEBUG option in debug developer builds, + # because qmake chooses and overrides the option when it gets appended to QMAKE_LFLAGS in + # qtbase\mkspecs\features\default_post.prf, regardless of what Chromium passes back from GN. + QMAKE_LFLAGS_DEBUG -= /DEBUG + QMAKE_LFLAGS_DEBUG += /DEBUG:FASTLINK + } QMAKE_LFLAGS += /WHOLEARCHIVE:$${api_library_path}$${QMAKE_DIR_SEP}$${api_library_name}.lib } else { LIBS_PRIVATE += -Wl,-whole-archive -l$$api_library_name -Wl,-no-whole-archive @@ -100,7 +113,7 @@ icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat resources.path = $$[QT_INSTALL_DATA]/resources INSTALLS += locales resources - !use?(system_icu) { + !qtConfig(system-icu) { icu.CONFIG += no_check_exist icu.path = $$[QT_INSTALL_DATA]/resources INSTALLS += icu @@ -112,7 +125,7 @@ icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat # Copy essential files to the qtbase build directory for non-prefix builds # - !use?(system_icu) { + !qtConfig(system-icu) { COPIES += icu } diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp index be0858310..12d429770 100644 --- a/src/core/delegated_frame_node.cpp +++ b/src/core/delegated_frame_node.cpp @@ -59,7 +59,8 @@ #include "base/threading/thread_task_runner_handle.h" #include "cc/base/math_util.h" #include "cc/output/bsp_tree.h" -#include "cc/output/delegated_frame_data.h" +#include "cc/output/compositor_frame.h" +#include "cc/output/compositor_frame_metadata.h" #include "cc/quads/debug_border_draw_quad.h" #include "cc/quads/draw_quad.h" #include "cc/quads/render_pass_draw_quad.h" @@ -70,7 +71,7 @@ #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 "components/viz/display_compositor/host_shared_bitmap_manager.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_fence.h" @@ -83,13 +84,8 @@ #include <QSGTexture> #include <private/qsgadaptationlayer_p.h> -#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)) #include <QSGImageNode> #include <QSGRectangleNode> -#else -#include <QSGSimpleRectNode> -#include <QSGSimpleTextureNode> -#endif #if !defined(QT_NO_EGL) #include <EGL/egl.h> @@ -211,7 +207,6 @@ protected: QVector<QSGNode*> *m_sceneGraphNodes; }; -#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)) class DelegatedNodeTreeUpdater : public DelegatedNodeTreeHandler { public: @@ -243,8 +238,11 @@ public: QSGNode *) override { QSGTextureNode *textureNode = static_cast<QSGTextureNode*>(*m_nodeIterator++); - if (textureNode->texture() != texture) + if (textureNode->texture() != texture) { textureNode->setTexture(texture); + // @TODO: This is a workaround for funky rendering, figure out why this is needed. + textureNode->markDirty(QSGTextureNode::DirtyGeometry); + } if (textureNode->textureCoordinatesTransform() != texCoordTransForm) textureNode->setTextureCoordinatesTransform(texCoordTransForm); if (textureNode->rect() != rect) @@ -258,15 +256,17 @@ public: QSGTexture::Filtering filtering, QSGNode *) override { QSGTextureNode *textureNode = static_cast<QSGTextureNode*>(*m_nodeIterator++); - + if (textureNode->texture() != texture) { + textureNode->setTexture(texture); + // @TODO: This is a workaround for funky rendering, figure out why this is needed. + textureNode->markDirty(QSGTextureNode::DirtyGeometry); + } 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 *) override { @@ -306,7 +306,6 @@ public: private: QVector<QSGNode*>::iterator m_nodeIterator; }; -#endif class DelegatedNodeTreeCreator : public DelegatedNodeTreeHandler { @@ -437,9 +436,9 @@ private: }; -static inline QSharedPointer<QSGLayer> findRenderPassLayer(const cc::RenderPassId &id, const QVector<QPair<cc::RenderPassId, QSharedPointer<QSGLayer> > > &list) +static inline QSharedPointer<QSGLayer> findRenderPassLayer(const int &id, const QVector<QPair<int, QSharedPointer<QSGLayer> > > &list) { - typedef QPair<cc::RenderPassId, QSharedPointer<QSGLayer> > Pair; + typedef QPair<int, QSharedPointer<QSGLayer> > Pair; Q_FOREACH (const Pair &pair, list) if (pair.first == id) return pair.second; @@ -660,7 +659,7 @@ QSharedPointer<QSGTexture> ResourceHolder::initTexture(bool quadNeedsBlending, R if (!texture) { if (m_resource.is_software) { Q_ASSERT(apiDelegate); - std::unique_ptr<cc::SharedBitmap> sharedBitmap = content::HostSharedBitmapManager::current()->GetSharedBitmapFromId(m_resource.size, m_resource.mailbox_holder.mailbox); + std::unique_ptr<cc::SharedBitmap> sharedBitmap = viz::HostSharedBitmapManager::current()->GetSharedBitmapFromId(m_resource.size, m_resource.mailbox_holder.mailbox); // QSG interprets QImage::hasAlphaChannel meaning that a node should enable blending // to draw it but Chromium keeps this information in the quads. // The input format is currently always Format_ARGB32_Premultiplied, so assume that all @@ -755,7 +754,7 @@ void DelegatedFrameNode::preprocess() fetchAndSyncMailboxes(mailboxesToFetch); // Then render any intermediate RenderPass in order. - typedef QPair<cc::RenderPassId, QSharedPointer<QSGLayer> > Pair; + typedef QPair<int, QSharedPointer<QSGLayer> > Pair; Q_FOREACH (const Pair &pair, m_sgObjects.renderPassLayers) { // The layer is non-live, request a one-time update here. pair.second->scheduleUpdate(); @@ -793,8 +792,8 @@ static bool areSharedQuadStatesEqual(const cc::SharedQuadState *layerState, // 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) +static bool areRenderPassStructuresEqual(cc::CompositorFrame *frameData, + cc::CompositorFrame *previousFrameData) { if (!previousFrameData) return false; @@ -842,8 +841,8 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, RenderWidgetHostViewQtDelegate *apiDelegate) { m_chromiumCompositorData = chromiumCompositorData; - cc::DelegatedFrameData* frameData = m_chromiumCompositorData->frameData.get(); - if (!frameData) + cc::CompositorFrame* frameData = &m_chromiumCompositorData->frameData; + if (frameData->render_pass_list.empty()) return; // DelegatedFrameNode is a transform node only for the purpose of @@ -876,15 +875,10 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, // 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. -#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)) - cc::DelegatedFrameData *previousFrameData = m_chromiumCompositorData->previousFrameData.get(); + cc::CompositorFrame *previousFrameData = &m_chromiumCompositorData->previousFrameData; const bool buildNewTree = !areRenderPassStructuresEqual(frameData, previousFrameData) || m_sceneGraphNodes.empty(); -#else - // No updates possible with old scenegraph nodes - const bool buildNewTree = true; -#endif - m_chromiumCompositorData->previousFrameData = nullptr; + m_chromiumCompositorData->previousFrameData = cc::CompositorFrame(); SGObjects previousSGObjects; QVector<QSharedPointer<QSGTexture> > textureStrongRefs; if (buildNewTree) { @@ -896,13 +890,11 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, delete oldChain; m_sceneGraphNodes.clear(); nodeHandler.reset(new DelegatedNodeTreeCreator(&m_sceneGraphNodes, apiDelegate)); -#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)) } 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)); -#endif } // 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. @@ -933,7 +925,7 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData, } QSharedPointer<QSGRootNode> rootNode(new QSGRootNode); rpLayer->setItem(rootNode.data()); - m_sgObjects.renderPassLayers.append(QPair<cc::RenderPassId, + m_sgObjects.renderPassLayers.append(QPair<int, QSharedPointer<QSGLayer> >(pass->id, rpLayer)); m_sgObjects.renderPassRootNodes.append(rootNode); renderPassParent = rootNode.data(); @@ -1250,27 +1242,15 @@ void DelegatedFrameNode::fetchAndSyncMailboxes(QList<MailboxTexture *> &mailboxe QMutexLocker lock(&m_mutex); gpu::SyncPointManager *syncPointManager = sync_point_manager(); - if (!m_syncPointClient) - m_syncPointClient = syncPointManager->CreateSyncPointClientWaiter(); base::MessageLoop *gpuMessageLoop = gpu_message_loop(); Q_ASSERT(m_numPendingSyncPoints == 0); m_numPendingSyncPoints = mailboxesToFetch.count(); - auto it = mailboxesToFetch.constBegin(); - auto end = mailboxesToFetch.constEnd(); - for (; it != end; ++it) { - MailboxTexture *mailboxTexture = *it; + for (MailboxTexture *mailboxTexture : qAsConst(mailboxesToFetch)) { gpu::SyncToken &syncToken = mailboxTexture->mailboxHolder().sync_token; - if (syncToken.HasData()) { - scoped_refptr<gpu::SyncPointClientState> release_state = - syncPointManager->GetSyncPointClientState(syncToken.namespace_id(), syncToken.command_buffer_id()); - if (release_state && !release_state->IsFenceSyncReleased(syncToken.release_count())) { - m_syncPointClient->WaitOutOfOrderNonThreadSafe( - release_state.get(), syncToken.release_count(), - gpuMessageLoop->task_runner(), base::Bind(&DelegatedFrameNode::pullTexture, this, mailboxTexture)); - continue; - } - } - gpuMessageLoop->task_runner()->PostTask(FROM_HERE, base::Bind(&DelegatedFrameNode::pullTexture, this, mailboxTexture)); + const auto task = base::Bind(&DelegatedFrameNode::pullTexture, this, mailboxTexture); + if (syncPointManager->WaitOutOfOrderNonThreadSafe(syncToken, gpuMessageLoop->task_runner(), task)) + continue; + gpuMessageLoop->task_runner()->PostTask(FROM_HERE, task); } m_mailboxesFetchedWaitCond.wait(&m_mutex); diff --git a/src/core/delegated_frame_node.h b/src/core/delegated_frame_node.h index cc682988d..cb8b1a5c3 100644 --- a/src/core/delegated_frame_node.h +++ b/src/core/delegated_frame_node.h @@ -40,6 +40,7 @@ #ifndef DELEGATED_FRAME_NODE_H #define DELEGATED_FRAME_NODE_H +#include "cc/output/compositor_frame.h" #include "cc/quads/render_pass.h" #include "cc/resources/transferable_resource.h" #include "gpu/command_buffer/service/sync_point_manager.h" @@ -80,8 +81,8 @@ class ChromiumCompositorData : public QSharedData { public: ChromiumCompositorData() : frameDevicePixelRatio(1) { } QHash<unsigned, QSharedPointer<ResourceHolder> > resourceHolders; - std::unique_ptr<cc::DelegatedFrameData> frameData; - std::unique_ptr<cc::DelegatedFrameData> previousFrameData; + cc::CompositorFrame frameData; + cc::CompositorFrame previousFrameData; qreal frameDevicePixelRatio; }; @@ -129,7 +130,7 @@ private: QExplicitlySharedDataPointer<ChromiumCompositorData> m_chromiumCompositorData; struct SGObjects { - QVector<QPair<cc::RenderPassId, QSharedPointer<QSGLayer> > > renderPassLayers; + QVector<QPair<int, QSharedPointer<QSGLayer> > > renderPassLayers; QVector<QSharedPointer<QSGRootNode> > renderPassRootNodes; QVector<QSharedPointer<QSGTexture> > textureStrongRefs; } m_sgObjects; @@ -138,7 +139,6 @@ private: QWaitCondition m_mailboxesFetchedWaitCond; QMutex m_mutex; QList<gl::TransferableFence> m_textureFences; - std::unique_ptr<gpu::SyncPointClient> m_syncPointClient; #if defined(USE_X11) bool m_contextShared; QScopedPointer<QOffscreenSurface> m_offsurface; diff --git a/src/core/desktop_screen_qt.cpp b/src/core/desktop_screen_qt.cpp index 1f4c9730f..b63511c92 100644 --- a/src/core/desktop_screen_qt.cpp +++ b/src/core/desktop_screen_qt.cpp @@ -70,17 +70,18 @@ int DesktopScreenQt::GetNumDisplays() const return 0; } -std::vector<display::Display> DesktopScreenQt::GetAllDisplays() const +std::vector<display::Display>& DesktopScreenQt::GetAllDisplays() const { Q_UNREACHABLE(); - return std::vector<display::Display>(); + static std::vector<display::Display> empty; + return empty; } -display::Display DesktopScreenQt::GetDisplayNearestWindow(gfx::NativeView window) const +display::Display DesktopScreenQt::GetDisplayNearestWindow(gfx::NativeWindow window) const { // RenderViewHostImpl::OnStartDragging uses this to determine // the scale factor for the view. - return display::Display(); + return display::Display(0); } display::Display DesktopScreenQt::GetDisplayNearestPoint(const gfx::Point& point) const @@ -97,7 +98,7 @@ display::Display DesktopScreenQt::GetDisplayMatching(const gfx::Rect& match_rect display::Display DesktopScreenQt::GetPrimaryDisplay() const { - return display::Display(); + return display::Display(0); } void DesktopScreenQt::AddObserver(display::DisplayObserver* observer) diff --git a/src/core/desktop_screen_qt.h b/src/core/desktop_screen_qt.h index f052461a2..0c52c615a 100644 --- a/src/core/desktop_screen_qt.h +++ b/src/core/desktop_screen_qt.h @@ -51,8 +51,8 @@ public: bool IsWindowUnderCursor(gfx::NativeWindow) override; gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) override; int GetNumDisplays() const override; - std::vector<display::Display> GetAllDisplays() const override; - display::Display GetDisplayNearestWindow(gfx::NativeView window) const override; + std::vector<display::Display>& GetAllDisplays() const override; + display::Display GetDisplayNearestWindow(gfx::NativeWindow window) const override; display::Display GetDisplayNearestPoint(const gfx::Point& point) const override; display::Display GetDisplayMatching(const gfx::Rect& match_rect) const override; display::Display GetPrimaryDisplay() const override; diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp index 77469a8ea..5eb97c5ea 100644 --- a/src/core/download_manager_delegate_qt.cpp +++ b/src/core/download_manager_delegate_qt.cpp @@ -81,7 +81,7 @@ void DownloadManagerDelegateQt::GetNextId(const content::DownloadIdCallback& cal void DownloadManagerDelegateQt::cancelDownload(const content::DownloadTargetCallback& callback) { - callback.Run(base::FilePath(), content::DownloadItem::TARGET_DISPOSITION_PROMPT, content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, base::FilePath()); + callback.Run(base::FilePath(), content::DownloadItem::TARGET_DISPOSITION_PROMPT, content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, base::FilePath(), content::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED); } void DownloadManagerDelegateQt::cancelDownload(quint32 downloadId) @@ -92,6 +92,22 @@ void DownloadManagerDelegateQt::cancelDownload(quint32 downloadId) download->Cancel(/* user_cancel */ true); } +void DownloadManagerDelegateQt::pauseDownload(quint32 downloadId) +{ + content::DownloadManager* dlm = content::BrowserContext::GetDownloadManager(m_contextAdapter->browserContext()); + content::DownloadItem *download = dlm->GetDownload(downloadId); + if (download) + download->Pause(); +} + +void DownloadManagerDelegateQt::resumeDownload(quint32 downloadId) +{ + content::DownloadManager* dlm = content::BrowserContext::GetDownloadManager(m_contextAdapter->browserContext()); + content::DownloadItem *download = dlm->GetDownload(downloadId); + if (download) + download->Resume(); +} + bool DownloadManagerDelegateQt::DetermineDownloadTarget(content::DownloadItem* item, const content::DownloadTargetCallback& callback) { @@ -100,7 +116,7 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(content::DownloadItem* i // store downloads and other special downloads, so they might never end up here anyway. if (!item->GetForcedFilePath().empty()) { callback.Run(item->GetForcedFilePath(), content::DownloadItem::TARGET_DISPOSITION_PROMPT, - content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, item->GetForcedFilePath()); + content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, item->GetForcedFilePath(), content::DOWNLOAD_INTERRUPT_REASON_NONE); return true; } @@ -155,6 +171,8 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(content::DownloadItem* i suggestedFilePath, BrowserContextAdapterClient::UnknownSavePageFormat, false /* accepted */, + false /* paused */, + false /* done */, m_downloadType, item->GetLastReason() }; @@ -178,8 +196,11 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(content::DownloadItem* i } base::FilePath filePathForCallback(toFilePathString(suggestedFile.absoluteFilePath())); - callback.Run(filePathForCallback, content::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, filePathForCallback.AddExtension(toFilePathString("download"))); + callback.Run(filePathForCallback, + content::DownloadItem::TARGET_DISPOSITION_OVERWRITE, + content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, + filePathForCallback.AddExtension(toFilePathString("download")), + content::DOWNLOAD_INTERRUPT_REASON_NONE); } else cancelDownload(callback); @@ -245,6 +266,8 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content suggestedFilePath, suggestedSaveFormat, acceptedByDefault, + false, /* paused */ + false, /* done */ BrowserContextAdapterClient::SavePage, BrowserContextAdapterClient::NoReason }; @@ -283,6 +306,8 @@ void DownloadManagerDelegateQt::OnDownloadUpdated(content::DownloadItem *downloa QString(), BrowserContextAdapterClient::UnknownSavePageFormat, true /* accepted */, + download->IsPaused(), + download->IsDone(), m_downloadType, download->GetLastReason() }; diff --git a/src/core/download_manager_delegate_qt.h b/src/core/download_manager_delegate_qt.h index cd21d330c..aec83cb41 100644 --- a/src/core/download_manager_delegate_qt.h +++ b/src/core/download_manager_delegate_qt.h @@ -83,6 +83,8 @@ public: const content::SavePackagePathPickedCallback &callback) override; void cancelDownload(quint32 downloadId); + void pauseDownload(quint32 downloadId); + void resumeDownload(quint32 downloadId); void setDownloadType(int downloadType) { m_downloadType = downloadType; } diff --git a/src/core/gl_context_qt.cpp b/src/core/gl_context_qt.cpp index 8f812a9cb..cd82b1069 100644 --- a/src/core/gl_context_qt.cpp +++ b/src/core/gl_context_qt.cpp @@ -93,21 +93,20 @@ void GLContextHelper::destroy() contextHelper = 0; } -bool GLContextHelper::initializeContextOnBrowserThread(gl::GLContext* context, gl::GLSurface* surface) +bool GLContextHelper::initializeContextOnBrowserThread(gl::GLContext* context, gl::GLSurface* surface, gl::GLContextAttribs attribs) { - gl::GLContextAttribs attribs; - attribs.gpu_preference = gl::PreferDiscreteGpu; return context->Initialize(surface, attribs); } -bool GLContextHelper::initializeContext(gl::GLContext* context, gl::GLSurface* surface) +bool GLContextHelper::initializeContext(gl::GLContext* context, gl::GLSurface* surface, gl::GLContextAttribs attribs) { bool ret = false; Qt::ConnectionType connType = (QThread::currentThread() == qApp->thread()) ? Qt::DirectConnection : Qt::BlockingQueuedConnection; QMetaObject::invokeMethod(contextHelper, "initializeContextOnBrowserThread", connType, Q_RETURN_ARG(bool, ret), Q_ARG(gl::GLContext*, context), - Q_ARG(gl::GLSurface*, surface)); + Q_ARG(gl::GLSurface*, surface), + Q_ARG(gl::GLContextAttribs, attribs)); return ret; } @@ -171,7 +170,7 @@ scoped_refptr<GLContext> CreateGLContext(GLShareGroup* share_group, scoped_refptr<GLContext> context = new GLContextEGL(share_group); #endif - if (!GLContextHelper::initializeContext(context.get(), compatible_surface)) + if (!GLContextHelper::initializeContext(context.get(), compatible_surface, attribs)) return NULL; return context; diff --git a/src/core/gl_context_qt.h b/src/core/gl_context_qt.h index 47cd7dc7f..9c8a43a0a 100644 --- a/src/core/gl_context_qt.h +++ b/src/core/gl_context_qt.h @@ -41,6 +41,7 @@ #define GL_GL_CONTEXT_QT_H_ #include <QObject> +#include "ui/gl/gl_context.h" namespace gl { class GLContext; @@ -54,7 +55,7 @@ class GLContextHelper : public QObject { public: static void initialize(); static void destroy(); - static bool initializeContext(gl::GLContext* context, gl::GLSurface* surface); + static bool initializeContext(gl::GLContext* context, gl::GLSurface* surface, gl::GLContextAttribs attribs); static void* getEGLConfig(); static void* getXConfig(); @@ -63,7 +64,7 @@ public: static void* getNativeDisplay(); private: - Q_INVOKABLE bool initializeContextOnBrowserThread(gl::GLContext* context, gl::GLSurface* surface); + Q_INVOKABLE bool initializeContextOnBrowserThread(gl::GLContext* context, gl::GLSurface* surface, gl::GLContextAttribs attribs); static GLContextHelper* contextHelper; }; diff --git a/src/core/gl_surface_qt.cpp b/src/core/gl_surface_qt.cpp index a18e22b58..f731b0231 100644 --- a/src/core/gl_surface_qt.cpp +++ b/src/core/gl_surface_qt.cpp @@ -103,7 +103,7 @@ public: static bool InitializeOneOff(); - bool Initialize() override; + bool Initialize(GLSurfaceFormat format) override; void Destroy() override; void* GetHandle() override; bool Resize(const gfx::Size& size, float scale_factor, bool has_alpha) override; @@ -125,7 +125,7 @@ public: explicit GLSurfacelessQtEGL(const gfx::Size& size); public: - bool Initialize() override; + bool Initialize(GLSurfaceFormat format) override; void Destroy() override; bool IsSurfaceless() const override; bool Resize(const gfx::Size& size, float scale_factor, bool has_alpha) override; @@ -153,7 +153,7 @@ public: static bool InitializeOneOff(); - bool Initialize() override; + bool Initialize(GLSurfaceFormat format) override; void Destroy() override; void* GetHandle() override; @@ -180,6 +180,16 @@ bool GLSurfaceGLX::IsCreateContextRobustnessSupported() return false; // ExtensionsContain(g_extensions, "GLX_ARB_create_context_robustness"); } +bool GLSurfaceGLX::IsEXTSwapControlSupported() +{ + return HasGLXExtension("GLX_EXT_swap_control"); +} + +bool GLSurfaceGLX::IsMESASwapControlSupported() +{ + return HasGLXExtension("GLX_MESA_swap_control"); +} + bool GLSurfaceGLX::IsCreateContextProfileSupported() { return false; // ExtensionsContain(g_extensions, "GLX_ARB_create_context_profile"); @@ -247,7 +257,7 @@ bool GLSurfaceQtGLX::InitializeOneOff() return true; } -bool GLSurfaceQtGLX::Initialize() +bool GLSurfaceQtGLX::Initialize(GLSurfaceFormat format) { Q_ASSERT(!m_surfaceBuffer); @@ -261,6 +271,7 @@ bool GLSurfaceQtGLX::Initialize() }; m_surfaceBuffer = glXCreatePbuffer(display, static_cast<GLXFBConfig>(g_config), pbuffer_attributes); + m_format = format; if (!m_surfaceBuffer) { Destroy(); @@ -297,7 +308,7 @@ public: static bool InitializeOneOff(); - bool Initialize() override; + bool Initialize(GLSurfaceFormat format) override; void Destroy() override; void *GetHandle() override; void *GetDisplay() override; @@ -327,11 +338,12 @@ bool GLSurfaceQtWGL::InitializeOneOff() return GLSurfaceWGL::InitializeOneOff(); } -bool GLSurfaceQtWGL::Initialize() +bool GLSurfaceQtWGL::Initialize(GLSurfaceFormat format) { m_surfaceBuffer = new PbufferGLSurfaceWGL(m_size); + m_format = format; - return m_surfaceBuffer->Initialize(gl::GLSurface::SURFACE_DEFAULT); + return m_surfaceBuffer->Initialize(format); } void GLSurfaceQtWGL::Destroy() @@ -426,6 +438,15 @@ bool GLSurfaceEGL::IsCreateContextWebGLCompatabilitySupported() return false; } +bool GLSurfaceEGL::IsEGLContextPrioritySupported() +{ + return false; +} + +void GLSurfaceEGL::ShutdownOneOff() +{ +} + const char* GLSurfaceEGL::GetEGLExtensions() { return g_extensions; @@ -436,6 +457,11 @@ bool GLSurfaceEGL::HasEGLExtension(const char* name) return ExtensionsContain(GetEGLExtensions(), name); } +bool GLSurfaceEGL::InitializeOneOff(EGLNativeDisplayType /*native_display*/) +{ + return GLSurfaceQtEGL::InitializeOneOff(); +} + GLSurfaceQt::GLSurfaceQt(const gfx::Size& size) : m_size(size) { @@ -456,9 +482,10 @@ GLSurfaceQtEGL::GLSurfaceQtEGL(const gfx::Size& size) { } -bool GLSurfaceQtEGL::Initialize() +bool GLSurfaceQtEGL::Initialize(GLSurfaceFormat format) { Q_ASSERT(!m_surfaceBuffer); + m_format = format; EGLDisplay display = g_display; if (!display) { @@ -513,6 +540,12 @@ gfx::Size GLSurfaceQt::GetSize() } +GLSurfaceFormat GLSurfaceQt::GetFormat() +{ + return m_format; +} + + bool GLSurfaceQtEGL::Resize(const gfx::Size& size, float scale_factor, bool has_alpha) { if (size == m_size) @@ -527,7 +560,7 @@ bool GLSurfaceQtEGL::Resize(const gfx::Size& size, float scale_factor, bool has_ m_size = size; - if (!Initialize()) { + if (!Initialize(GetFormat())) { LOG(ERROR) << "Failed to resize pbuffer."; return false; } @@ -558,8 +591,9 @@ GLSurfacelessQtEGL::GLSurfacelessQtEGL(const gfx::Size& size) { } -bool GLSurfacelessQtEGL::Initialize() +bool GLSurfacelessQtEGL::Initialize(GLSurfaceFormat format) { + m_format = format; return true; } @@ -625,7 +659,7 @@ bool usingSoftwareDynamicGL() } scoped_refptr<GLSurface> -CreateOffscreenGLSurface(const gfx::Size& size) +CreateOffscreenGLSurfaceWithFormat(const gfx::Size& size, GLSurfaceFormat format) { scoped_refptr<GLSurface> surface; switch (GetGLImplementation()) { @@ -633,13 +667,13 @@ CreateOffscreenGLSurface(const gfx::Size& size) case kGLImplementationDesktopGL: { #if defined(OS_WIN) surface = new GLSurfaceQtWGL(size); - if (surface->Initialize()) + if (surface->Initialize(format)) return surface; break; #elif defined(USE_X11) if (!g_initializedEGL) { surface = new GLSurfaceQtGLX(size); - if (surface->Initialize()) + if (surface->Initialize(format)) return surface; } // no break @@ -647,7 +681,7 @@ CreateOffscreenGLSurface(const gfx::Size& size) } case kGLImplementationEGLGLES2: { surface = new GLSurfaceQtEGL(size); - if (surface->Initialize()) + if (surface->Initialize(format)) return surface; // Surfaceless context will be used ONLY if pseudo surfaceless context @@ -655,7 +689,7 @@ CreateOffscreenGLSurface(const gfx::Size& size) // have problems. (e.g. QTBUG-57290) if (g_egl_surfaceless_context_supported) { surface = new GLSurfacelessQtEGL(size); - if (surface->Initialize()) + if (surface->Initialize(format)) return surface; } LOG(WARNING) << "Failed to create offscreen GL surface"; @@ -695,7 +729,7 @@ namespace gpu { class GpuCommandBufferStub; class GpuChannelManager; scoped_refptr<gl::GLSurface> ImageTransportSurface::CreateNativeSurface(base::WeakPtr<ImageTransportSurfaceDelegate>, - SurfaceHandle, gl::GLSurface::Format) + SurfaceHandle, gl::GLSurfaceFormat) { QT_NOT_USED return scoped_refptr<gl::GLSurface>(); diff --git a/src/core/gl_surface_qt.h b/src/core/gl_surface_qt.h index 08b501846..c26cb7ed0 100644 --- a/src/core/gl_surface_qt.h +++ b/src/core/gl_surface_qt.h @@ -59,12 +59,14 @@ public: bool IsOffscreen() override; gfx::SwapResult SwapBuffers() override; gfx::Size GetSize() override; + GLSurfaceFormat GetFormat() override; protected: GLSurfaceQt(); virtual ~GLSurfaceQt(); gfx::Size m_size; + GLSurfaceFormat m_format; private: DISALLOW_COPY_AND_ASSIGN(GLSurfaceQt); diff --git a/src/core/gn_run.pro b/src/core/gn_run.pro index ee4e7892e..c565b99a4 100644 --- a/src/core/gn_run.pro +++ b/src/core/gn_run.pro @@ -1,7 +1,5 @@ -isQtMinimum(5, 8) { - include($$QTWEBENGINE_OUT_ROOT/qtwebengine-config.pri) - QT_FOR_CONFIG += webengine-private -} +include($$QTWEBENGINE_OUT_ROOT/qtwebengine-config.pri) +QT_FOR_CONFIG += webengine-private TEMPLATE = aux diff --git a/src/core/javascript_dialog_manager_qt.cpp b/src/core/javascript_dialog_manager_qt.cpp index 5fac12dd3..a1a8604a4 100644 --- a/src/core/javascript_dialog_manager_qt.cpp +++ b/src/core/javascript_dialog_manager_qt.cpp @@ -48,14 +48,17 @@ namespace QtWebEngineCore { -Q_STATIC_ASSERT_X(static_cast<int>(content::JAVASCRIPT_MESSAGE_TYPE_PROMPT) == static_cast<int>(WebContentsAdapterClient::PromptDialog), "These enums should be in sync."); +ASSERT_ENUMS_MATCH(content::JAVASCRIPT_DIALOG_TYPE_ALERT, WebContentsAdapterClient::AlertDialog) +ASSERT_ENUMS_MATCH(content::JAVASCRIPT_DIALOG_TYPE_CONFIRM, WebContentsAdapterClient::ConfirmDialog) +ASSERT_ENUMS_MATCH(content::JAVASCRIPT_DIALOG_TYPE_PROMPT, WebContentsAdapterClient::PromptDialog) + JavaScriptDialogManagerQt *JavaScriptDialogManagerQt::GetInstance() { return base::Singleton<JavaScriptDialogManagerQt>::get(); } -void JavaScriptDialogManagerQt::RunJavaScriptDialog(content::WebContents *webContents, const GURL &originUrl, content::JavaScriptMessageType javascriptMessageType, const base::string16 &messageText, const base::string16 &defaultPromptText, const content::JavaScriptDialogManager::DialogClosedCallback &callback, bool *didSuppressMessage) +void JavaScriptDialogManagerQt::RunJavaScriptDialog(content::WebContents *webContents, const GURL &originUrl, content::JavaScriptDialogType dialog_type, const base::string16 &messageText, const base::string16 &defaultPromptText, const content::JavaScriptDialogManager::DialogClosedCallback &callback, bool *didSuppressMessage) { WebContentsAdapterClient *client = WebContentsViewQt::from(static_cast<content::WebContentsImpl*>(webContents)->GetView())->client(); if (!client) { @@ -64,7 +67,7 @@ void JavaScriptDialogManagerQt::RunJavaScriptDialog(content::WebContents *webCon return; } - WebContentsAdapterClient::JavascriptDialogType dialogType = static_cast<WebContentsAdapterClient::JavascriptDialogType>(javascriptMessageType); + WebContentsAdapterClient::JavascriptDialogType dialogType = static_cast<WebContentsAdapterClient::JavascriptDialogType>(dialog_type); runDialogForContents(webContents, dialogType, toQt(messageText).toHtmlEscaped(), toQt(defaultPromptText).toHtmlEscaped(), toQt(originUrl.GetOrigin()), callback); } diff --git a/src/core/javascript_dialog_manager_qt.h b/src/core/javascript_dialog_manager_qt.h index ad2a54cac..291f027a9 100644 --- a/src/core/javascript_dialog_manager_qt.h +++ b/src/core/javascript_dialog_manager_qt.h @@ -40,7 +40,6 @@ #define JAVASCRIPT_DIALOG_MANAGER_QT_H #include "content/public/browser/javascript_dialog_manager.h" -#include "content/public/common/javascript_message_type.h" #include "web_contents_adapter_client.h" @@ -60,13 +59,15 @@ public: // For use with the Singleton helper class from chromium static JavaScriptDialogManagerQt *GetInstance(); - void RunJavaScriptDialog(content::WebContents *, const GURL &, content::JavaScriptMessageType javascriptMessageType, + void RunJavaScriptDialog(content::WebContents *, const GURL &, content::JavaScriptDialogType dialog_type, const base::string16 &messageText, const base::string16 &defaultPromptText, - const content::JavaScriptDialogManager::DialogClosedCallback &callback, bool *didSuppressMessage) override; + const content::JavaScriptDialogManager::DialogClosedCallback &callback, + bool *didSuppressMessage) override; - void RunBeforeUnloadDialog(content::WebContents *, bool isReload, const content::JavaScriptDialogManager::DialogClosedCallback &callback) override; + void RunBeforeUnloadDialog(content::WebContents *, bool isReload, + const content::JavaScriptDialogManager::DialogClosedCallback &callback) override; bool HandleJavaScriptDialog(content::WebContents *, bool accept, const base::string16 *promptOverride) override; - void CancelDialogs(content::WebContents *contents, bool /*suppress_callbacks*/, bool /*reset_state*/) override + void CancelDialogs(content::WebContents *contents, bool /*reset_state*/) override { takeDialogForContents(contents); } diff --git a/src/core/media_capture_devices_dispatcher.cpp b/src/core/media_capture_devices_dispatcher.cpp index 105e85ec6..87fe543b1 100644 --- a/src/core/media_capture_devices_dispatcher.cpp +++ b/src/core/media_capture_devices_dispatcher.cpp @@ -62,9 +62,13 @@ #include "content/public/common/media_stream_request.h" #include "media/audio/audio_device_description.h" #include "media/audio/audio_manager_base.h" +#include "media/media_features.h" +#include "ui/base/l10n/l10n_util.h" + +#if BUILDFLAG(ENABLE_WEBRTC) #include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h" #include "third_party/webrtc/modules/desktop_capture/desktop_capturer.h" -#include "ui/base/l10n/l10n_util.h" +#endif #include <QtCore/qcoreapplication.h> @@ -117,13 +121,51 @@ std::unique_ptr<content::MediaStreamUI> getDevicesForDesktopCapture(content::Med return std::move(ui); } +content::DesktopMediaID getDefaultScreenId() +{ +#if BUILDFLAG(ENABLE_WEBRTC) + // Source id patterns are different across platforms. + // On Linux, the hardcoded value "0" is used. + // On Windows, the screens are enumerated consecutively in increasing order from 0. + // On macOS the source ids are randomish numbers assigned by the OS. + + // In order to provide a correct screen id, we query for the available screen ids, and + // select the first one as the main display id. + // The code is based on the file + // src/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc. + webrtc::DesktopCaptureOptions options = + webrtc::DesktopCaptureOptions::CreateDefault(); + options.set_disable_effects(false); + std::unique_ptr<webrtc::DesktopCapturer> screen_capturer( + webrtc::DesktopCapturer::CreateScreenCapturer(options)); + + if (screen_capturer) { + webrtc::DesktopCapturer::SourceList screens; + if (screen_capturer->GetSourceList(&screens)) { + if (screens.size() > 0) { + return content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, screens[0].id); + } + } + } +#endif + + return content::DesktopMediaID(content::DesktopMediaID::TYPE_SCREEN, 0); +} + WebContentsAdapterClient::MediaRequestFlags mediaRequestFlagsForRequest(const content::MediaStreamRequest &request) { WebContentsAdapterClient::MediaRequestFlags requestFlags = WebContentsAdapterClient::MediaNone; + if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE) requestFlags |= WebContentsAdapterClient::MediaAudioCapture; + else if (request.audio_type == content::MEDIA_DESKTOP_AUDIO_CAPTURE) + requestFlags |= WebContentsAdapterClient::MediaDesktopAudioCapture; + if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE) requestFlags |= WebContentsAdapterClient::MediaVideoCapture; + else if (request.video_type == content::MEDIA_DESKTOP_VIDEO_CAPTURE) + requestFlags |= WebContentsAdapterClient::MediaDesktopVideoCapture; + return requestFlags; } @@ -146,6 +188,7 @@ void MediaCaptureDevicesDispatcher::handleMediaAccessPermissionResponse(content: { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + std::unique_ptr<content::MediaStreamUI> ui; content::MediaStreamDevices devices; std::map<content::WebContents*, RequestsQueue>::iterator it = m_pendingRequests.find(webContents); @@ -172,16 +215,30 @@ void MediaCaptureDevicesDispatcher::handleMediaAccessPermissionResponse(content: (request.audio_type && authorizationFlags & WebContentsAdapterClient::MediaAudioCapture); bool webcamRequested = (request.video_type && authorizationFlags & WebContentsAdapterClient::MediaVideoCapture); - if (securityOriginsMatch && (microphoneRequested || webcamRequested)) { - switch (request.request_type) { - case content::MEDIA_OPEN_DEVICE_PEPPER_ONLY: - getDefaultDevices("", "", microphoneRequested, webcamRequested, &devices); - break; - case content::MEDIA_DEVICE_ACCESS: - case content::MEDIA_GENERATE_STREAM: - getDefaultDevices(request.requested_audio_device_id, request.requested_video_device_id, - microphoneRequested, webcamRequested, &devices); - break; + bool desktopAudioRequested = + (request.audio_type && authorizationFlags & WebContentsAdapterClient::MediaDesktopAudioCapture); + bool desktopVideoRequested = + (request.video_type && authorizationFlags & WebContentsAdapterClient::MediaDesktopVideoCapture); + + if (securityOriginsMatch) { + if (microphoneRequested || webcamRequested) { + switch (request.request_type) { + case content::MEDIA_OPEN_DEVICE_PEPPER_ONLY: + getDefaultDevices("", "", microphoneRequested, webcamRequested, &devices); + break; + case content::MEDIA_DEVICE_ACCESS: + case content::MEDIA_GENERATE_STREAM: + getDefaultDevices(request.requested_audio_device_id, request.requested_video_device_id, + microphoneRequested, webcamRequested, &devices); + break; + } + } else if (desktopVideoRequested) { + ui = getDevicesForDesktopCapture( + &devices, + getDefaultScreenId(), + desktopAudioRequested, + /* display_notification: */ false, + getContentsUrl(webContents)); } } @@ -196,7 +253,7 @@ void MediaCaptureDevicesDispatcher::handleMediaAccessPermissionResponse(content: BrowserThread::UI, FROM_HERE, base::Bind(&MediaCaptureDevicesDispatcher::ProcessQueuedAccessRequest, base::Unretained(this), webContents)); } - callback.Run(devices, devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE : content::MEDIA_DEVICE_OK, std::unique_ptr<content::MediaStreamUI>()); + callback.Run(devices, devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE : content::MEDIA_DEVICE_OK, std::move(ui)); } @@ -234,22 +291,34 @@ void MediaCaptureDevicesDispatcher::processMediaAccessRequest(WebContentsAdapter , const content::MediaStreamRequest &request , const content::MediaResponseCallback &callback) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - // Let's not support tab capture for now. - if (request.video_type == content::MEDIA_TAB_VIDEO_CAPTURE || request.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE) - return; - - if (request.video_type == content::MEDIA_DESKTOP_VIDEO_CAPTURE || request.audio_type == content::MEDIA_DESKTOP_AUDIO_CAPTURE) - // It's still unclear what to make of screen capture. We can rely on existing javascript dialog infrastructure - // to experiment with this without exposing it through our API yet. - processDesktopCaptureAccessRequest(webContents, request, callback); - else { - enqueueMediaAccessRequest(webContents, request, callback); - // We might not require this approval for pepper requests. - adapterClient->runMediaAccessPermissionRequest(toQt(request.security_origin), mediaRequestFlagsForRequest(request)); - } + // Let's not support tab capture for now. + if (request.video_type == content::MEDIA_TAB_VIDEO_CAPTURE || request.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE) { + callback.Run(content::MediaStreamDevices(), content::MEDIA_DEVICE_NOT_SUPPORTED, std::unique_ptr<content::MediaStreamUI>()); + return; + } + if (request.video_type == content::MEDIA_DESKTOP_VIDEO_CAPTURE || + request.audio_type == content::MEDIA_DESKTOP_AUDIO_CAPTURE) { + const bool screenCaptureEnabled = + adapterClient->webEngineSettings()->testAttribute(WebEngineSettings::ScreenCaptureEnabled); + const bool originIsSecure = content::IsOriginSecure(request.security_origin); + if (!screenCaptureEnabled || !originIsSecure) { + callback.Run(content::MediaStreamDevices(), content::MEDIA_DEVICE_INVALID_STATE, std::unique_ptr<content::MediaStreamUI>()); + return; + } + + if (!request.requested_video_device_id.empty()) { + // Non-empty device id from the chooseDesktopMedia() extension API. + processDesktopCaptureAccessRequest(webContents, request, callback); + return; + } + } + + enqueueMediaAccessRequest(webContents, request, callback); + // We might not require this approval for pepper requests. + adapterClient->runMediaAccessPermissionRequest(toQt(request.security_origin), mediaRequestFlagsForRequest(request)); } void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content::WebContents *webContents, const content::MediaStreamRequest &request @@ -258,19 +327,12 @@ void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content:: content::MediaStreamDevices devices; std::unique_ptr<content::MediaStreamUI> ui; - if (request.video_type != content::MEDIA_DESKTOP_VIDEO_CAPTURE) { + if (request.video_type != content::MEDIA_DESKTOP_VIDEO_CAPTURE || + request.requested_video_device_id.empty()) { callback.Run(devices, content::MEDIA_DEVICE_INVALID_STATE, std::move(ui)); return; } - // If the device id wasn't specified then this is a screen capture request - // (i.e. chooseDesktopMedia() API wasn't used to generate device id). - if (request.requested_video_device_id.empty()) { - processScreenCaptureAccessRequest( - webContents, request, callback); - return; - } - content::WebContents* const web_contents_for_stream = content::WebContents::FromRenderFrameHost( content::RenderFrameHost::FromID(request.render_process_id, request.render_frame_id)); content::RenderFrameHost* const main_frame = web_contents_for_stream ? web_contents_for_stream->GetMainFrame() : NULL; @@ -303,84 +365,6 @@ void MediaCaptureDevicesDispatcher::processDesktopCaptureAccessRequest(content:: callback.Run(devices, devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE : content::MEDIA_DEVICE_OK, std::move(ui)); } -void MediaCaptureDevicesDispatcher::processScreenCaptureAccessRequest(content::WebContents *webContents, const content::MediaStreamRequest &request - ,const content::MediaResponseCallback &callback) -{ - DCHECK_EQ(request.video_type, content::MEDIA_DESKTOP_VIDEO_CAPTURE); - - WebContentsAdapterClient *adapterClient = WebContentsViewQt::from(static_cast<content::WebContentsImpl*>(webContents)->GetView())->client(); - const bool screenCaptureEnabled = adapterClient->webEngineSettings()->testAttribute(WebEngineSettings::ScreenCaptureEnabled); - - const bool originIsSecure = content::IsOriginSecure(request.security_origin); - - if (screenCaptureEnabled && originIsSecure) { - - enqueueMediaAccessRequest(webContents, request, callback); - base::Callback<void(bool, const base::string16&)> dialogCallback = base::Bind(&MediaCaptureDevicesDispatcher::handleScreenCaptureAccessRequest, - base::Unretained(this), base::Unretained(webContents)); - - QUrl securityOrigin(toQt(request.security_origin)); - QString message = QCoreApplication::translate("MediaCaptureDevicesDispatcher", "Do you want %1 to share your screen?").arg(securityOrigin.toString()); - QString title = QCoreApplication::translate("MediaCaptureDevicesDispatcher", "%1 Screen Sharing request").arg(securityOrigin.toString()); - JavaScriptDialogManagerQt::GetInstance()->runDialogForContents(webContents, WebContentsAdapterClient::InternalAuthorizationDialog, message - , QString(), securityOrigin, dialogCallback, title); - } else - callback.Run(content::MediaStreamDevices(), content::MEDIA_DEVICE_INVALID_STATE, std::unique_ptr<content::MediaStreamUI>()); -} - -void MediaCaptureDevicesDispatcher::handleScreenCaptureAccessRequest(content::WebContents *webContents, bool userAccepted, const base::string16 &) -{ - content::MediaStreamDevices devices; - std::unique_ptr<content::MediaStreamUI> ui; - if (userAccepted) { - // Source id patterns are different across platforms. - // On Linux, the hardcoded value "0" is used. - // On Windows, the screens are enumerated consecutively in increasing order from 0. - // On macOS the source ids are randomish numbers assigned by the OS. - webrtc::DesktopCapturer::SourceId id = 0; - -#if defined(ENABLE_WEBRTC) - // In order to provide a correct screen id, we query for the available screen ids, and - // select the first one as the main display id. - // The code is based on the file - // src/chrome/browser/extensions/api/desktop_capture/desktop_capture_base.cc. - webrtc::DesktopCaptureOptions options = - webrtc::DesktopCaptureOptions::CreateDefault(); - options.set_disable_effects(false); - std::unique_ptr<webrtc::DesktopCapturer> screen_capturer( - webrtc::DesktopCapturer::CreateScreenCapturer(options)); - - if (screen_capturer) { - webrtc::DesktopCapturer::SourceList screens; - if (screen_capturer->GetSourceList(&screens)) { - if (screens.size() > 0) { - id = screens[0].id; - } - } - } -#endif - - content::DesktopMediaID screenId = content::DesktopMediaID( - content::DesktopMediaID::TYPE_SCREEN, id); - ui = getDevicesForDesktopCapture(&devices, screenId, false/*capture_audio*/, false/*display_notification*/, getContentsUrl(webContents)); - } - std::map<content::WebContents*, RequestsQueue>::iterator it = - m_pendingRequests.find(webContents); - if (it == m_pendingRequests.end()) { - // WebContents has been destroyed. Don't need to do anything. - return; - } - - RequestsQueue &queue(it->second); - if (queue.empty()) - return; - - content::MediaResponseCallback callback = queue.front().callback; - queue.pop_front(); - - callback.Run(devices, devices.empty() ? content::MEDIA_DEVICE_INVALID_STATE : content::MEDIA_DEVICE_OK, std::move(ui)); -} - void MediaCaptureDevicesDispatcher::enqueueMediaAccessRequest(content::WebContents *webContents, const content::MediaStreamRequest &request ,const content::MediaResponseCallback &callback) { diff --git a/src/core/media_capture_devices_dispatcher.h b/src/core/media_capture_devices_dispatcher.h index c378c327e..579d159a4 100644 --- a/src/core/media_capture_devices_dispatcher.h +++ b/src/core/media_capture_devices_dispatcher.h @@ -116,8 +116,6 @@ class MediaCaptureDevicesDispatcher : public content::MediaObserver, // Helpers for ProcessMediaAccessRequest(). void processDesktopCaptureAccessRequest(content::WebContents *, const content::MediaStreamRequest &, const content::MediaResponseCallback &); - void processScreenCaptureAccessRequest(content::WebContents *,const content::MediaStreamRequest &, const content::MediaResponseCallback &); - void handleScreenCaptureAccessRequest(content::WebContents *, bool userAccepted, const base::string16 &/*unused callback_input*/); void enqueueMediaAccessRequest(content::WebContents *, const content::MediaStreamRequest &, const content::MediaResponseCallback &); void ProcessQueuedAccessRequest(content::WebContents *); diff --git a/src/core/native_web_keyboard_event_qt.cpp b/src/core/native_web_keyboard_event_qt.cpp index 86fa5c8b1..9eb613e25 100644 --- a/src/core/native_web_keyboard_event_qt.cpp +++ b/src/core/native_web_keyboard_event_qt.cpp @@ -66,9 +66,9 @@ using blink::WebKeyboardEvent; namespace content { -NativeWebKeyboardEvent::NativeWebKeyboardEvent() - : os_event(0), - skip_in_browser(false) +NativeWebKeyboardEvent::NativeWebKeyboardEvent(blink::WebInputEvent::Type, int, base::TimeTicks) + : os_event(0) + , skip_in_browser(false) { } diff --git a/src/core/network_delegate_qt.cpp b/src/core/network_delegate_qt.cpp index 9b4c415c9..6507ac1cc 100644 --- a/src/core/network_delegate_qt.cpp +++ b/src/core/network_delegate_qt.cpp @@ -311,12 +311,27 @@ bool NetworkDelegateQt::OnAreExperimentalCookieFeaturesEnabled() const return false; } -bool NetworkDelegateQt::OnAreStrictSecureCookiesEnabled() const +bool NetworkDelegateQt::OnCancelURLRequestWithPolicyViolatingReferrerHeader(const net::URLRequest&, const GURL&, const GURL&) const { return false; } -bool NetworkDelegateQt::OnCancelURLRequestWithPolicyViolatingReferrerHeader(const net::URLRequest&, const GURL&, const GURL&) const +bool NetworkDelegateQt::OnCanQueueReportingReport(const url::Origin& origin) const +{ + return false; +} + +bool NetworkDelegateQt::OnCanSendReportingReport(const url::Origin& origin) const +{ + return false; +} + +bool NetworkDelegateQt::OnCanSetReportingClient(const url::Origin& origin, const GURL& endpoint) const +{ + return false; +} + +bool NetworkDelegateQt::OnCanUseReportingClient(const url::Origin& origin, const GURL& endpoint) const { return false; } diff --git a/src/core/network_delegate_qt.h b/src/core/network_delegate_qt.h index 4ded56a9d..590b3b20c 100644 --- a/src/core/network_delegate_qt.h +++ b/src/core/network_delegate_qt.h @@ -92,8 +92,14 @@ public: virtual bool OnCanAccessFile(const net::URLRequest& request, const base::FilePath& path) const override; virtual bool OnCanEnablePrivacyMode(const GURL&, const GURL&) const override; virtual bool OnAreExperimentalCookieFeaturesEnabled() const override; - virtual bool OnAreStrictSecureCookiesEnabled() const override; virtual bool OnCancelURLRequestWithPolicyViolatingReferrerHeader(const net::URLRequest&, const GURL&, const GURL&) const override; + + virtual bool OnCanQueueReportingReport(const url::Origin& origin) const override; + virtual bool OnCanSendReportingReport(const url::Origin& origin) const override; + virtual bool OnCanSetReportingClient(const url::Origin& origin, + const GURL& endpoint) const override; + virtual bool OnCanUseReportingClient(const url::Origin& origin, + const GURL& endpoint) const override; }; } // namespace QtWebEngineCore diff --git a/src/core/ozone_platform_qt.cpp b/src/core/ozone_platform_qt.cpp index 9cdafa279..e165239bd 100644 --- a/src/core/ozone_platform_qt.cpp +++ b/src/core/ozone_platform_qt.cpp @@ -99,6 +99,7 @@ public: // PlatformEventDispatcher: bool CanDispatchEvent(const PlatformEvent& event) override; uint32_t DispatchEvent(const PlatformEvent& event) override; + void PrepareForShutdown() override; private: PlatformWindowDelegate* delegate_; @@ -134,6 +135,11 @@ uint32_t PlatformWindowQt::DispatchEvent(const ui::PlatformEvent& native_event) return ui::POST_DISPATCH_STOP_PROPAGATION; } +void PlatformWindowQt::PrepareForShutdown() +{ +} + + class OzonePlatformQt : public OzonePlatform { public: OzonePlatformQt(); @@ -143,14 +149,14 @@ public: ui::CursorFactoryOzone* GetCursorFactoryOzone() override; GpuPlatformSupportHost* GetGpuPlatformSupportHost() override; std::unique_ptr<PlatformWindow> CreatePlatformWindow(PlatformWindowDelegate* delegate, const gfx::Rect& bounds) override; - std::unique_ptr<ui::NativeDisplayDelegate> CreateNativeDisplayDelegate() override; + std::unique_ptr<display::NativeDisplayDelegate> CreateNativeDisplayDelegate() override; ui::InputController* GetInputController() override; std::unique_ptr<ui::SystemInputInjector> CreateSystemInputInjector() override; ui::OverlayManagerOzone* GetOverlayManager() override; private: - void InitializeUI() override; - void InitializeGPU() override; + void InitializeUI(const ui::OzonePlatform::InitParams &) override; + void InitializeGPU(const ui::OzonePlatform::InitParams &) override; std::unique_ptr<QtWebEngineCore::SurfaceFactoryQt> surface_factory_ozone_; std::unique_ptr<CursorFactoryOzone> cursor_factory_ozone_; @@ -202,13 +208,13 @@ ui::OverlayManagerOzone* OzonePlatformQt::GetOverlayManager() return overlay_manager_.get(); } -std::unique_ptr<ui::NativeDisplayDelegate> OzonePlatformQt::CreateNativeDisplayDelegate() +std::unique_ptr<display::NativeDisplayDelegate> OzonePlatformQt::CreateNativeDisplayDelegate() { NOTREACHED(); return nullptr; } -void OzonePlatformQt::InitializeUI() +void OzonePlatformQt::InitializeUI(const ui::OzonePlatform::InitParams &) { overlay_manager_.reset(new StubOverlayManager()); cursor_factory_ozone_.reset(new CursorFactoryOzone()); @@ -216,7 +222,7 @@ void OzonePlatformQt::InitializeUI() input_controller_ = CreateStubInputController(); } -void OzonePlatformQt::InitializeGPU() +void OzonePlatformQt::InitializeGPU(const ui::OzonePlatform::InitParams &) { surface_factory_ozone_.reset(new QtWebEngineCore::SurfaceFactoryQt()); } @@ -226,7 +232,7 @@ void OzonePlatformQt::InitializeGPU() OzonePlatform* CreateOzonePlatformQt() { return new OzonePlatformQt; } -ClientNativePixmapFactory* CreateClientNativePixmapFactoryQt() +gfx::ClientNativePixmapFactory* CreateClientNativePixmapFactoryQt() { return CreateStubClientNativePixmapFactory(); } diff --git a/src/core/pdfium_document_wrapper_qt.cpp b/src/core/pdfium_document_wrapper_qt.cpp index 7c43c77db..df829a426 100644 --- a/src/core/pdfium_document_wrapper_qt.cpp +++ b/src/core/pdfium_document_wrapper_qt.cpp @@ -36,7 +36,12 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#if defined (ENABLE_PDF) +#include "pdf/features.h" +#if BUILDFLAG(ENABLE_PDF) +#define ENABLE_PDF +#endif + +#if defined(ENABLE_PDF) #include "pdfium_document_wrapper_qt.h" #include <QtCore/qhash.h> diff --git a/src/core/permission_manager_qt.cpp b/src/core/permission_manager_qt.cpp index 970a608a3..4c941406c 100644 --- a/src/core/permission_manager_qt.cpp +++ b/src/core/permission_manager_qt.cpp @@ -202,14 +202,6 @@ void PermissionManagerQt::ResetPermission( m_permissions.remove(key); } -void PermissionManagerQt::RegisterPermissionUsage( - content::PermissionType /*permission*/, - const GURL& /*requesting_origin*/, - const GURL& /*embedding_origin*/) -{ - // We do not currently track which permissions are used. -} - int PermissionManagerQt::SubscribePermissionStatusChange( content::PermissionType permission, const GURL& requesting_origin, diff --git a/src/core/permission_manager_qt.h b/src/core/permission_manager_qt.h index 1cbb41b5e..e98174762 100644 --- a/src/core/permission_manager_qt.h +++ b/src/core/permission_manager_qt.h @@ -87,11 +87,6 @@ public: const base::Callback<void( const std::vector<blink::mojom::PermissionStatus>&)>& callback) override; - void RegisterPermissionUsage( - content::PermissionType permission, - const GURL& requesting_origin, - const GURL& embedding_origin) override; - int SubscribePermissionStatusChange( content::PermissionType permission, const GURL& requesting_origin, diff --git a/src/core/print_view_manager_base_qt.cpp b/src/core/print_view_manager_base_qt.cpp index a5d832529..cbd8ea03a 100644 --- a/src/core/print_view_manager_base_qt.cpp +++ b/src/core/print_view_manager_base_qt.cpp @@ -72,7 +72,9 @@ PrintViewManagerBaseQt::PrintViewManagerBaseQt(content::WebContents *contents) : printing::PrintManager(contents) , cookie_(0) , m_isInsideInnerMessageLoop(false) +#if !defined(OS_MACOSX) , m_isExpectingFirstPage(false) +#endif , m_didPrintingSucceed(false) , m_printerQueriesQueue(WebEngineContext::current()->getPrintJobManager()->queue()) { diff --git a/src/core/print_view_manager_base_qt.h b/src/core/print_view_manager_base_qt.h index 511a104bf..4e4c8bde2 100644 --- a/src/core/print_view_manager_base_qt.h +++ b/src/core/print_view_manager_base_qt.h @@ -149,7 +149,9 @@ private: base::Closure m_quitClosure; bool m_isInsideInnerMessageLoop; +#if !defined(OS_MACOSX) bool m_isExpectingFirstPage; +#endif bool m_didPrintingSucceed; scoped_refptr<printing::PrintQueriesQueue> m_printerQueriesQueue; // content::WebContentsObserver implementation. diff --git a/src/core/print_view_manager_qt.cpp b/src/core/print_view_manager_qt.cpp index f2d78365d..b8df5a131 100644 --- a/src/core/print_view_manager_qt.cpp +++ b/src/core/print_view_manager_qt.cpp @@ -60,6 +60,7 @@ #include "content/public/common/web_preferences.h" #include "printing/pdf_metafile_skia.h" #include "printing/print_job_constants.h" +#include "printing/units.h" DEFINE_WEB_CONTENTS_USER_DATA_KEY(QtWebEngineCore::PrintViewManagerQt); @@ -132,6 +133,10 @@ static base::DictionaryValue *createPrintSettings() printSettings->SetBoolean(printing::kSettingGenerateDraftData, false); printSettings->SetBoolean(printing::kSettingPreviewModifiable, false); + + printSettings->SetInteger(printing::kSettingDpiHorizontal, printing::kPointsPerInch); + printSettings->SetInteger(printing::kSettingDpiVertical, printing::kPointsPerInch); + printSettings->SetInteger(printing::kSettingDuplexMode, printing::SIMPLEX); printSettings->SetInteger(printing::kSettingCopies, 1); printSettings->SetBoolean(printing::kSettingCollate, false); @@ -141,6 +146,7 @@ static base::DictionaryValue *createPrintSettings() printSettings->SetBoolean(printing::kSettingShouldPrintSelectionOnly, false); printSettings->SetBoolean(printing::kSettingShouldPrintBackgrounds, true); printSettings->SetBoolean(printing::kSettingHeaderFooterEnabled, false); + printSettings->SetBoolean(printing::kSettingRasterizePdf, false); printSettings->SetInteger(printing::kSettingScaleFactor, 100); printSettings->SetString(printing::kSettingDeviceName, ""); printSettings->SetInteger(printing::kPreviewUIID, 12345678); diff --git a/src/core/qtwebengine.gni b/src/core/qtwebengine.gni index bb269baa2..c9f766a36 100644 --- a/src/core/qtwebengine.gni +++ b/src/core/qtwebengine.gni @@ -1,3 +1,4 @@ +import("//media/media_options.gni") import("//third_party/widevine/cdm/widevine.gni") chromium_version = exec_script("//build/util/version.py", [ "-f", rebase_path("//chrome/VERSION"), @@ -11,6 +12,7 @@ include_dirs = [ deps = [ "//base", + "//chrome/common:features", "//components/error_page/common", "//components/keyed_service/content", "//components/visitedlink/browser", @@ -22,10 +24,11 @@ deps = [ "//content/public/browser", "//content/public/common", "//content/public/renderer", + "//media:media_features", "//net:net_browser_services", + "//net:net_with_v8", "//skia", "//third_party/WebKit/public:blink", - "//third_party/webrtc/base:base", "//ui/accessibility", "//third_party/mesa:mesa_headers", ":qtwebengine_sources", @@ -36,6 +39,10 @@ if (enable_widevine) { deps += [ "//components/cdm/renderer"] } +if (enable_webrtc) { + deps += [ "//third_party/webrtc/base:base" ] +} + if (is_linux && !is_desktop_linux) { deps += [ "//ui/events/ozone:events_ozone_evdev"] } diff --git a/src/core/qtwebengine_resources.gni b/src/core/qtwebengine_resources.gni index a7ffb40f3..acf5f1590 100644 --- a/src/core/qtwebengine_resources.gni +++ b/src/core/qtwebengine_resources.gni @@ -70,7 +70,7 @@ repack("qtwebengine_repack_resources_200") { repack("qtwebengine_repack_resources_devtools") { sources = [ - "$root_gen_dir/blink/devtools_resources.pak", + "$root_gen_dir/content/browser/devtools/devtools_resources.pak", ] output = "$root_out_dir/qtwebengine_devtools_resources.pak" deps = [ diff --git a/src/core/qtwebengine_sources.gni b/src/core/qtwebengine_sources.gni index 9a559732d..d7fe4d70d 100644 --- a/src/core/qtwebengine_sources.gni +++ b/src/core/qtwebengine_sources.gni @@ -1,5 +1,8 @@ import("//build/config/features.gni") +import("//build/config/ui.gni") import("//components/spellcheck/spellcheck_build_features.gni") +import("//pdf/features.gni") +import("//ppapi/features/features.gni") import("//printing/features/features.gni") source_set("qtwebengine_spellcheck_sources") { @@ -18,6 +21,7 @@ source_set("qtwebengine_spellcheck_sources") { deps = [ "//components/spellcheck/browser", "//components/spellcheck/renderer", + "//third_party/boringssl", "//third_party/WebKit/public:blink", "//third_party/hunspell", ] @@ -43,8 +47,8 @@ source_set("qtwebengine_sources") { "//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", + "//components/prefs/in_memory_pref_store.cc", + "//components/prefs/in_memory_pref_store.h", "//extensions/common/constants.cc", "//extensions/common/constants.h", "//extensions/common/url_pattern.cc", @@ -99,10 +103,10 @@ source_set("qtwebengine_sources") { if (enable_pdf) { deps += [ "//pdf", + "//pdf:features", "//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 980550620..136371a91 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -73,6 +73,7 @@ #include "ui/gfx/geometry/size_conversions.h" #if defined(USE_AURA) +#include "ui/base/cursor/cursor.h" #include "ui/base/cursor/cursors_aura.h" #endif @@ -105,9 +106,9 @@ enum ImStateFlags { static inline ui::LatencyInfo CreateLatencyInfo(const blink::WebInputEvent& event) { ui::LatencyInfo latency_info; // The latency number should only be added if the timestamp is valid. - if (event.timeStampSeconds) { + if (event.TimeStampSeconds()) { const int64_t time_micros = static_cast<int64_t>( - event.timeStampSeconds * base::Time::kMicrosecondsPerSecond); + event.TimeStampSeconds() * base::Time::kMicrosecondsPerSecond); latency_info.AddLatencyNumberWithTimestamp( ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, @@ -218,7 +219,8 @@ public: } int GetFlags() const override { return flags; } float GetPressure(size_t pointer_index) const override { return touchPoints.at(pointer_index).pressure(); } - float GetTilt(size_t pointer_index) const override { return 0; } + float GetTiltX(size_t pointer_index) const override { return 0; } + float GetTiltY(size_t pointer_index) const override { return 0; } base::TimeTicks GetEventTime() const override { return eventTime; } size_t GetHistorySize() const override { return 0; } @@ -261,12 +263,15 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost* widget , m_needsDelegatedFrameAck(false) , m_loadVisuallyCommittedState(NotCommitted) , m_adapterClient(0) + , m_rendererCompositorFrameSink(0) , m_imeInProgress(false) , m_receivedEmptyImeText(false) , m_initPending(false) , m_beginFrameSource(nullptr) , m_needsBeginFrames(false) + , m_needsFlushInput(false) , m_addedFrameObserver(false) + , m_backgroundColor(SK_ColorWHITE) , m_imState(0) , m_anchorPositionWithinSelection(-1) , m_cursorPositionWithinSelection(-1) @@ -444,12 +449,20 @@ gfx::Rect RenderWidgetHostViewQt::GetViewBounds() const return gfx::BoundingRect(p1, p2); } +SkColor RenderWidgetHostViewQt::background_color() const +{ + return m_backgroundColor; +} + void RenderWidgetHostViewQt::SetBackgroundColor(SkColor color) { - RenderWidgetHostViewBase::SetBackgroundColor(color); + if (m_backgroundColor == color) + return; + m_backgroundColor = color; // Set the background of the compositor if necessary m_delegate->setClearColor(toQt(color)); // Set the background of the blink::FrameView + m_host->SetBackgroundOpaque(SkColorGetA(color) == SK_AlphaOPAQUE); m_host->Send(new RenderViewObserverQt_SetBackgroundColor(m_host->GetRoutingID(), color)); } @@ -473,119 +486,119 @@ void RenderWidgetHostViewQt::UnlockMouse() void RenderWidgetHostViewQt::UpdateCursor(const content::WebCursor &webCursor) { - content::WebCursor::CursorInfo cursorInfo; + content::CursorInfo cursorInfo; webCursor.GetCursorInfo(&cursorInfo); Qt::CursorShape shape = Qt::ArrowCursor; #if defined(USE_AURA) - int auraType = -1; + ui::CursorType auraType = ui::CursorType::kNull; #endif switch (cursorInfo.type) { - case blink::WebCursorInfo::TypePointer: + case blink::WebCursorInfo::kTypePointer: shape = Qt::ArrowCursor; break; - case blink::WebCursorInfo::TypeCross: + case blink::WebCursorInfo::kTypeCross: shape = Qt::CrossCursor; break; - case blink::WebCursorInfo::TypeHand: + case blink::WebCursorInfo::kTypeHand: shape = Qt::PointingHandCursor; break; - case blink::WebCursorInfo::TypeIBeam: + case blink::WebCursorInfo::kTypeIBeam: shape = Qt::IBeamCursor; break; - case blink::WebCursorInfo::TypeWait: + case blink::WebCursorInfo::kTypeWait: shape = Qt::WaitCursor; break; - case blink::WebCursorInfo::TypeHelp: + case blink::WebCursorInfo::kTypeHelp: shape = Qt::WhatsThisCursor; break; - case blink::WebCursorInfo::TypeEastResize: - case blink::WebCursorInfo::TypeWestResize: - case blink::WebCursorInfo::TypeEastWestResize: - case blink::WebCursorInfo::TypeEastPanning: - case blink::WebCursorInfo::TypeWestPanning: + case blink::WebCursorInfo::kTypeEastResize: + case blink::WebCursorInfo::kTypeWestResize: + case blink::WebCursorInfo::kTypeEastWestResize: + case blink::WebCursorInfo::kTypeEastPanning: + case blink::WebCursorInfo::kTypeWestPanning: shape = Qt::SizeHorCursor; break; - case blink::WebCursorInfo::TypeNorthResize: - case blink::WebCursorInfo::TypeSouthResize: - case blink::WebCursorInfo::TypeNorthSouthResize: - case blink::WebCursorInfo::TypeNorthPanning: - case blink::WebCursorInfo::TypeSouthPanning: + case blink::WebCursorInfo::kTypeNorthResize: + case blink::WebCursorInfo::kTypeSouthResize: + case blink::WebCursorInfo::kTypeNorthSouthResize: + case blink::WebCursorInfo::kTypeNorthPanning: + case blink::WebCursorInfo::kTypeSouthPanning: shape = Qt::SizeVerCursor; break; - case blink::WebCursorInfo::TypeNorthEastResize: - case blink::WebCursorInfo::TypeSouthWestResize: - case blink::WebCursorInfo::TypeNorthEastSouthWestResize: - case blink::WebCursorInfo::TypeNorthEastPanning: - case blink::WebCursorInfo::TypeSouthWestPanning: + case blink::WebCursorInfo::kTypeNorthEastResize: + case blink::WebCursorInfo::kTypeSouthWestResize: + case blink::WebCursorInfo::kTypeNorthEastSouthWestResize: + case blink::WebCursorInfo::kTypeNorthEastPanning: + case blink::WebCursorInfo::kTypeSouthWestPanning: shape = Qt::SizeBDiagCursor; break; - case blink::WebCursorInfo::TypeNorthWestResize: - case blink::WebCursorInfo::TypeSouthEastResize: - case blink::WebCursorInfo::TypeNorthWestSouthEastResize: - case blink::WebCursorInfo::TypeNorthWestPanning: - case blink::WebCursorInfo::TypeSouthEastPanning: + case blink::WebCursorInfo::kTypeNorthWestResize: + case blink::WebCursorInfo::kTypeSouthEastResize: + case blink::WebCursorInfo::kTypeNorthWestSouthEastResize: + case blink::WebCursorInfo::kTypeNorthWestPanning: + case blink::WebCursorInfo::kTypeSouthEastPanning: shape = Qt::SizeFDiagCursor; break; - case blink::WebCursorInfo::TypeColumnResize: + case blink::WebCursorInfo::kTypeColumnResize: shape = Qt::SplitHCursor; break; - case blink::WebCursorInfo::TypeRowResize: + case blink::WebCursorInfo::kTypeRowResize: shape = Qt::SplitVCursor; break; - case blink::WebCursorInfo::TypeMiddlePanning: - case blink::WebCursorInfo::TypeMove: + case blink::WebCursorInfo::kTypeMiddlePanning: + case blink::WebCursorInfo::kTypeMove: shape = Qt::SizeAllCursor; break; - case blink::WebCursorInfo::TypeProgress: + case blink::WebCursorInfo::kTypeProgress: shape = Qt::BusyCursor; break; #if defined(USE_AURA) - case blink::WebCursorInfo::TypeVerticalText: - auraType = ui::kCursorVerticalText; + case blink::WebCursorInfo::kTypeVerticalText: + auraType = ui::CursorType::kVerticalText; break; - case blink::WebCursorInfo::TypeCell: - auraType = ui::kCursorCell; + case blink::WebCursorInfo::kTypeCell: + auraType = ui::CursorType::kCell; break; - case blink::WebCursorInfo::TypeContextMenu: - auraType = ui::kCursorContextMenu; + case blink::WebCursorInfo::kTypeContextMenu: + auraType = ui::CursorType::kContextMenu; break; - case blink::WebCursorInfo::TypeAlias: - auraType = ui::kCursorAlias; + case blink::WebCursorInfo::kTypeAlias: + auraType = ui::CursorType::kAlias; break; - case blink::WebCursorInfo::TypeCopy: - auraType = ui::kCursorCopy; + case blink::WebCursorInfo::kTypeCopy: + auraType = ui::CursorType::kCopy; break; - case blink::WebCursorInfo::TypeZoomIn: - auraType = ui::kCursorZoomIn; + case blink::WebCursorInfo::kTypeZoomIn: + auraType = ui::CursorType::kZoomIn; break; - case blink::WebCursorInfo::TypeZoomOut: - auraType = ui::kCursorZoomOut; + case blink::WebCursorInfo::kTypeZoomOut: + auraType = ui::CursorType::kZoomOut; break; #else - case blink::WebCursorInfo::TypeVerticalText: - case blink::WebCursorInfo::TypeCell: - case blink::WebCursorInfo::TypeContextMenu: - case blink::WebCursorInfo::TypeAlias: - case blink::WebCursorInfo::TypeCopy: - case blink::WebCursorInfo::TypeZoomIn: - case blink::WebCursorInfo::TypeZoomOut: + case blink::WebCursorInfo::kTypeVerticalText: + case blink::WebCursorInfo::kTypeCell: + case blink::WebCursorInfo::kTypeContextMenu: + case blink::WebCursorInfo::kTypeAlias: + case blink::WebCursorInfo::kTypeCopy: + case blink::WebCursorInfo::kTypeZoomIn: + case blink::WebCursorInfo::kTypeZoomOut: // FIXME: Support on OS X break; #endif - case blink::WebCursorInfo::TypeNoDrop: - case blink::WebCursorInfo::TypeNotAllowed: + case blink::WebCursorInfo::kTypeNoDrop: + case blink::WebCursorInfo::kTypeNotAllowed: shape = Qt::ForbiddenCursor; break; - case blink::WebCursorInfo::TypeNone: + case blink::WebCursorInfo::kTypeNone: shape = Qt::BlankCursor; break; - case blink::WebCursorInfo::TypeGrab: + case blink::WebCursorInfo::kTypeGrab: shape = Qt::OpenHandCursor; break; - case blink::WebCursorInfo::TypeGrabbing: + case blink::WebCursorInfo::kTypeGrabbing: shape = Qt::ClosedHandCursor; break; - case blink::WebCursorInfo::TypeCustom: + case blink::WebCursorInfo::kTypeCustom: if (cursorInfo.custom_image.colorType() == SkColorType::kN32_SkColorType) { QImage cursor = toQImage(cursorInfo.custom_image, QImage::Format_ARGB32); m_delegate->updateCursor(QCursor(QPixmap::fromImage(cursor), cursorInfo.hotspot.x(), cursorInfo.hotspot.y())); @@ -594,7 +607,7 @@ void RenderWidgetHostViewQt::UpdateCursor(const content::WebCursor &webCursor) break; } #if defined(USE_AURA) - if (auraType > 0) { + if (auraType != ui::CursorType::kNull) { SkBitmap bitmap; gfx::Point hotspot; if (ui::GetCursorBitmap(auraType, &bitmap, &hotspot)) { @@ -640,54 +653,36 @@ void RenderWidgetHostViewQt::SetTooltipText(const base::string16 &tooltip_text) m_adapterClient->setToolTip(toQt(tooltip_text)); } -void RenderWidgetHostViewQt::CopyFromCompositingSurface(const gfx::Rect& src_subrect, const gfx::Size& dst_size, const content::ReadbackRequestCallback& callback, const SkColorType color_type) -{ - NOTIMPLEMENTED(); - Q_UNUSED(src_subrect); - Q_UNUSED(dst_size); - Q_UNUSED(color_type); - callback.Run(SkBitmap(), content::READBACK_FAILED); -} - -void RenderWidgetHostViewQt::CopyFromCompositingSurfaceToVideoFrame(const gfx::Rect& src_subrect, const scoped_refptr<media::VideoFrame>& target, const base::Callback<void(const gfx::Rect&, bool)>& callback) -{ - NOTIMPLEMENTED(); - callback.Run(gfx::Rect(), false); -} - -bool RenderWidgetHostViewQt::CanCopyToVideoFrame() const -{ - return false; -} - bool RenderWidgetHostViewQt::HasAcceleratedSurface(const gfx::Size&) { return false; } -void RenderWidgetHostViewQt::LockCompositingSurface() -{ -} - -void RenderWidgetHostViewQt::UnlockCompositingSurface() +void RenderWidgetHostViewQt::DidCreateNewRendererCompositorFrameSink(cc::mojom::MojoCompositorFrameSinkClient *frameSink) { + // Accumulated resources belong to the old RendererCompositorFrameSink and + // should not be returned. + m_resourcesToRelease.clear(); + m_rendererCompositorFrameSink = frameSink; } -void RenderWidgetHostViewQt::OnSwapCompositorFrame(uint32_t output_surface_id, cc::CompositorFrame frame) +void RenderWidgetHostViewQt::SubmitCompositorFrame(const cc::LocalSurfaceId &local_surface_id, cc::CompositorFrame frame) { bool scrollOffsetChanged = (m_lastScrollOffset != frame.metadata.root_scroll_offset); bool contentsSizeChanged = (m_lastContentsSize != frame.metadata.root_layer_size); m_lastScrollOffset = frame.metadata.root_scroll_offset; m_lastContentsSize = frame.metadata.root_layer_size; + m_backgroundColor = frame.metadata.root_background_color; + if (m_localSurfaceId != local_surface_id) { + m_localSurfaceId = local_surface_id; + // FIXME: update frame_size and device_scale_factor? + // FIXME: showPrimarySurface()? + } Q_ASSERT(!m_needsDelegatedFrameAck); m_needsDelegatedFrameAck = true; - 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->previousFrameData = std::move(m_chromiumCompositorData->frameData); m_chromiumCompositorData->frameDevicePixelRatio = frame.metadata.device_scale_factor; + m_chromiumCompositorData->frameData = std::move(frame); // Support experimental.viewport.devicePixelRatio, see GetScreenInfo implementation below. float dpiScale = this->dpiScale(); @@ -789,8 +784,12 @@ void RenderWidgetHostViewQt::OnTextSelectionChanged(content::TextInputManager *t Q_UNUSED(text_input_manager); Q_UNUSED(updated_view); + const content::TextInputManager::TextSelection *selection = GetTextInputManager()->GetTextSelection(updated_view); + if (!selection) + return; + #if defined(USE_X11) - if (!GetSelectedText().empty()) { + if (!GetSelectedText().empty() && selection->user_initiated()) { // Set the CLIPBOARD_TYPE_SELECTION to the ui::Clipboard. ui::ScopedClipboardWriter clipboard_writer(ui::CLIPBOARD_TYPE_SELECTION); clipboard_writer.WriteText(GetSelectedText()); @@ -825,29 +824,34 @@ void RenderWidgetHostViewQt::selectionChanged() return; } - const content::TextInputManager::TextSelection *selection = text_input_manager_->GetTextSelection(); - if (!selection) + if (GetSelectedText().empty()) { + m_anchorPositionWithinSelection = m_cursorPosition; + m_cursorPositionWithinSelection = m_cursorPosition; + + if (!m_emptyPreviousSelection) { + m_emptyPreviousSelection = GetSelectedText().empty(); + m_adapterClient->selectionChanged(); + } + return; + } - if (!selection->range.IsValid()) + const content::TextInputManager::TextSelection *selection = text_input_manager_->GetTextSelection(); + if (!selection) return; - // Avoid duplicate empty selectionChanged() signals - if (GetSelectedText().empty() && m_emptyPreviousSelection) { - m_anchorPositionWithinSelection = m_cursorPosition; - m_cursorPositionWithinSelection = m_cursorPosition; + if (!selection->range().IsValid()) return; - } int newAnchorPositionWithinSelection = 0; int newCursorPositionWithinSelection = 0; if (text_input_manager_->GetSelectionRegion()->anchor.type() == gfx::SelectionBound::RIGHT) { - newAnchorPositionWithinSelection = selection->range.GetMax() - selection->offset; - newCursorPositionWithinSelection = selection->range.GetMin() - selection->offset; + newAnchorPositionWithinSelection = selection->range().GetMax() - selection->offset(); + newCursorPositionWithinSelection = selection->range().GetMin() - selection->offset(); } else { - newAnchorPositionWithinSelection = selection->range.GetMin() - selection->offset; - newCursorPositionWithinSelection = selection->range.GetMax() - selection->offset; + newAnchorPositionWithinSelection = selection->range().GetMin() - selection->offset(); + newCursorPositionWithinSelection = selection->range().GetMax() - selection->offset(); } if (m_anchorPositionWithinSelection == newAnchorPositionWithinSelection && m_cursorPositionWithinSelection == newCursorPositionWithinSelection) @@ -1006,17 +1010,17 @@ QVariant RenderWidgetHostViewQt::inputMethodQuery(Qt::InputMethodQuery query) void RenderWidgetHostViewQt::ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch, content::InputEventAckState ack_result) { Q_UNUSED(touch); const bool eventConsumed = ack_result == content::INPUT_EVENT_ACK_STATE_CONSUMED; - m_gestureProvider.OnTouchEventAck(touch.event.uniqueTouchEventId, eventConsumed); + m_gestureProvider.OnTouchEventAck(touch.event.unique_touch_event_id, eventConsumed); } void RenderWidgetHostViewQt::sendDelegatedFrameAck() { - m_beginFrameSource->DidFinishFrame(this, 0); + const cc::BeginFrameAck ack; + m_beginFrameSource->DidFinishFrame(this, ack); cc::ReturnedResourceArray resources; m_resourcesToRelease.swap(resources); - content::RenderWidgetHostImpl::SendReclaimCompositorResources( - m_host->GetRoutingID(), m_pendingOutputSurfaceId, - m_host->GetProcess()->GetID(), true, resources); + if (m_rendererCompositorFrameSink) + m_rendererCompositorFrameSink->DidReceiveCompositorFrameAck(resources); } void RenderWidgetHostViewQt::processMotionEvent(const ui::MotionEvent &motionEvent) @@ -1056,7 +1060,7 @@ float RenderWidgetHostViewQt::dpiScale() const bool RenderWidgetHostViewQt::IsPopup() const { - return popup_type_ != blink::WebPopupTypeNone; + return popup_type_ != blink::kWebPopupTypeNone; } void RenderWidgetHostViewQt::handleMouseEvent(QMouseEvent* event) @@ -1069,8 +1073,8 @@ void RenderWidgetHostViewQt::handleMouseEvent(QMouseEvent* event) return; blink::WebMouseEvent webEvent = WebEventFactory::toWebMouseEvent(event, dpiScale()); - if ((webEvent.type == blink::WebInputEvent::MouseDown || webEvent.type == blink::WebInputEvent::MouseUp) - && webEvent.button == blink::WebMouseEvent::Button::NoButton) { + if ((webEvent.GetType() == blink::WebInputEvent::kMouseDown || webEvent.GetType() == blink::WebInputEvent::kMouseUp) + && webEvent.button == blink::WebMouseEvent::Button::kNoButton) { // Blink can only handle the 3 main mouse-buttons and may assert when processing mouse-down for no button. return; } @@ -1083,13 +1087,13 @@ void RenderWidgetHostViewQt::handleMouseEvent(QMouseEvent* event) m_clickHelper.clickCounter = 0; m_clickHelper.lastPressTimestamp = event->timestamp(); - webEvent.clickCount = ++m_clickHelper.clickCounter; + webEvent.click_count = ++m_clickHelper.clickCounter; m_clickHelper.lastPressButton = event->button(); m_clickHelper.lastPressPosition = QPointF(event->pos()).toPoint(); } - webEvent.movementX = event->globalX() - m_previousMousePosition.x(); - webEvent.movementY = event->globalY() - m_previousMousePosition.y(); + webEvent.movement_x = event->globalX() - m_previousMousePosition.x(); + webEvent.movement_y = event->globalY() - m_previousMousePosition.y(); if (IsMouseLocked()) QCursor::setPos(m_previousMousePosition); @@ -1140,7 +1144,7 @@ void RenderWidgetHostViewQt::handleKeyEvent(QKeyEvent *ev) } content::NativeWebKeyboardEvent webEvent = WebEventFactory::toWebKeyboardEvent(ev); - bool keyDownTextInsertion = webEvent.type == blink::WebInputEvent::RawKeyDown && webEvent.text[0]; + bool keyDownTextInsertion = webEvent.GetType() == blink::WebInputEvent::kRawKeyDown && webEvent.text[0]; webEvent.skip_in_browser = keyDownTextInsertion; m_host->ForwardKeyboardEvent(webEvent); @@ -1149,7 +1153,7 @@ void RenderWidgetHostViewQt::handleKeyEvent(QKeyEvent *ev) // The RawKeyDown is skipped on the way back (see above). // The same os_event will be set on both NativeWebKeyboardEvents. webEvent.skip_in_browser = false; - webEvent.type = blink::WebInputEvent::Char; + webEvent.SetType(blink::WebInputEvent::kChar); m_host->ForwardKeyboardEvent(webEvent); } } @@ -1491,24 +1495,34 @@ void RenderWidgetHostViewQt::SetNeedsBeginFrames(bool needs_begin_frames) updateNeedsBeginFramesInternal(); } +void RenderWidgetHostViewQt::OnSetNeedsFlushInput() +{ + m_needsFlushInput = true; + updateNeedsBeginFramesInternal(); +} + void RenderWidgetHostViewQt::updateNeedsBeginFramesInternal() { if (!m_beginFrameSource) return; - if (m_addedFrameObserver == m_needsBeginFrames) + // Based on upstream Chromium commit 7f7c8cc8b97dd0d5c9159d9e60c62efbc35e6b53. + bool needsFrame = m_needsBeginFrames || m_needsFlushInput; + if (m_addedFrameObserver == needsFrame) return; - if (m_needsBeginFrames) + m_addedFrameObserver = needsFrame; + if (needsFrame) m_beginFrameSource->AddObserver(this); else m_beginFrameSource->RemoveObserver(this); - m_addedFrameObserver = m_needsBeginFrames; } bool RenderWidgetHostViewQt::OnBeginFrameDerivedImpl(const cc::BeginFrameArgs& args) { + m_needsFlushInput = false; m_beginFrameSource->OnUpdateVSyncParameters(args.frame_time, args.interval); + updateNeedsBeginFramesInternal(); m_host->Send(new ViewMsg_BeginFrame(m_host->GetRoutingID(), args)); return true; } diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h index ae3ce610c..63efad87e 100644 --- a/src/core/render_widget_host_view_qt.h +++ b/src/core/render_widget_host_view_qt.h @@ -138,6 +138,7 @@ public: void Hide() override; bool IsShowing() override; gfx::Rect GetViewBounds() const override; + SkColor background_color() const override; void SetBackgroundColor(SkColor color) override; bool LockMouse() override; void UnlockMouse() override; @@ -148,20 +149,16 @@ public: void RenderProcessGone(base::TerminationStatus, int) override; void Destroy() override; void SetTooltipText(const base::string16 &tooltip_text) override; - void CopyFromCompositingSurface(const gfx::Rect& src_subrect, const gfx::Size& dst_size, const content::ReadbackRequestCallback& callback, const SkColorType preferred_color_type) override; - void CopyFromCompositingSurfaceToVideoFrame(const gfx::Rect& src_subrect, const scoped_refptr<media::VideoFrame>& target, const base::Callback<void(const gfx::Rect&, bool)>& callback) override; - - bool CanCopyToVideoFrame() const override; bool HasAcceleratedSurface(const gfx::Size&) override; - void OnSwapCompositorFrame(uint32_t output_surface_id, cc::CompositorFrame frame) override; + void DidCreateNewRendererCompositorFrameSink(cc::mojom::MojoCompositorFrameSinkClient*) override; + void SubmitCompositorFrame(const cc::LocalSurfaceId&, cc::CompositorFrame) override; void GetScreenInfo(content::ScreenInfo* results); gfx::Rect GetBoundsInRootWindow() override; void ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch, content::InputEventAckState ack_result) override; void ClearCompositorFrame() override; - void LockCompositingSurface() override; - void UnlockCompositingSurface() override; void SetNeedsBeginFrames(bool needs_begin_frames) override; + void OnSetNeedsFlushInput() override; // Overridden from ui::GestureProviderClient. void OnGestureEvent(const ui::GestureEventData& gesture) override; @@ -245,11 +242,11 @@ private: cc::ReturnedResourceArray m_resourcesToRelease; bool m_needsDelegatedFrameAck; LoadVisuallyCommittedState m_loadVisuallyCommittedState; - uint32_t m_pendingOutputSurfaceId; QMetaObject::Connection m_adapterClientDestroyedConnection; WebContentsAdapterClient *m_adapterClient; MultipleMouseClickHelper m_clickHelper; + cc::mojom::MojoCompositorFrameSinkClient *m_rendererCompositorFrameSink; bool m_imeInProgress; bool m_receivedEmptyImeText; @@ -259,10 +256,13 @@ private: std::unique_ptr<cc::SyntheticBeginFrameSource> m_beginFrameSource; bool m_needsBeginFrames; + bool m_needsFlushInput; bool m_addedFrameObserver; gfx::Vector2dF m_lastScrollOffset; gfx::SizeF m_lastContentsSize; + SkColor m_backgroundColor; + cc::LocalSurfaceId m_localSurfaceId; uint m_imState; int m_anchorPositionWithinSelection; diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h index dda59a01a..7461e7608 100644 --- a/src/core/render_widget_host_view_qt_delegate.h +++ b/src/core/render_widget_host_view_qt_delegate.h @@ -58,16 +58,9 @@ class QVariant; class QWindow; class QInputMethodEvent; -#if (QT_VERSION < QT_VERSION_CHECK(5, 8, 0)) -class QSGImageNode; -typedef QSGImageNode QSGInternalImageNode; -class QSGSimpleTextureNode; -typedef QSGSimpleTextureNode QSGTextureNode; -#else class QSGInternalImageNode; class QSGImageNode; typedef QSGImageNode QSGTextureNode; -#endif QT_END_NAMESPACE diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp index ac6d7a2dc..83c4d719e 100644 --- a/src/core/renderer/content_renderer_client_qt.cpp +++ b/src/core/renderer/content_renderer_client_qt.cpp @@ -57,13 +57,15 @@ #include "components/visitedlink/renderer/visitedlink_slave.h" #include "components/web_cache/renderer/web_cache_impl.h" #include "content/public/renderer/render_frame.h" +#include "content/public/child/child_thread.h" +#include "content/public/common/service_manager_connection.h" +#include "content/public/common/simple_connection_filter.h" #include "content/public/renderer/render_thread.h" #include "content/public/renderer/render_view.h" #include "net/base/net_errors.h" #include "third_party/WebKit/public/platform/WebString.h" #include "third_party/WebKit/public/platform/WebURLError.h" #include "third_party/WebKit/public/platform/WebURLRequest.h" -#include "third_party/WebKit/public/web/WebSecurityPolicy.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/webui/jstemplate_builder.h" #include "content/public/common/web_preferences.h" @@ -76,7 +78,7 @@ #include "renderer/render_view_observer_qt.h" #include "renderer/user_resource_controller.h" #include "renderer/web_channel_ipc_transport.h" -#include "services/service_manager/public/cpp/interface_registry.h" +#include "services/service_manager/public/cpp/binder_registry.h" #include "components/grit/components_resources.h" @@ -85,7 +87,6 @@ namespace QtWebEngineCore { static const char kHttpErrorDomain[] = "http"; -static const char kQrcSchemeQt[] = "qrc"; ContentRendererClientQt::ContentRendererClientQt() { @@ -100,18 +101,22 @@ void ContentRendererClientQt::RenderThreadStarted() content::RenderThread *renderThread = content::RenderThread::Get(); m_visitedLinkSlave.reset(new visitedlink::VisitedLinkSlave); m_webCacheImpl.reset(new web_cache::WebCacheImpl()); - renderThread->GetInterfaceRegistry()->AddInterface( - m_visitedLinkSlave->GetBindCallback()); + + auto registry = base::MakeUnique<service_manager::BinderRegistry>(); + registry->AddInterface(m_visitedLinkSlave->GetBindCallback(), + base::ThreadTaskRunnerHandle::Get()); + content::ChildThread::Get() + ->GetServiceManagerConnection() + ->AddConnectionFilter(base::MakeUnique<content::SimpleConnectionFilter>( + std::move(registry))); + + renderThread->AddObserver(UserResourceController::instance()); #if BUILDFLAG(ENABLE_SPELLCHECK) m_spellCheck.reset(new SpellCheck()); renderThread->AddObserver(m_spellCheck.data()); #endif - - blink::WebString qrcScheme(base::ASCIIToUTF16(kQrcSchemeQt)); - // mark qrc as a secure scheme (avoids deprecation warnings) - blink::WebSecurityPolicy::registerURLSchemeAsSecure(qrcScheme); } void ContentRendererClientQt::RenderViewCreated(content::RenderView* render_view) @@ -120,15 +125,16 @@ void ContentRendererClientQt::RenderViewCreated(content::RenderView* render_view new RenderViewObserverQt(render_view, m_webCacheImpl.data()); new WebChannelIPCTransport(render_view); UserResourceController::instance()->renderViewCreated(render_view); -#if BUILDFLAG(ENABLE_SPELLCHECK) - new SpellCheckProvider(render_view, m_spellCheck.data()); -#endif - } void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame* render_frame) { new QtWebEngineCore::RenderFrameObserverQt(render_frame); + UserResourceController::instance()->renderFrameCreated(render_frame); + +#if BUILDFLAG(ENABLE_SPELLCHECK) + new SpellCheckProvider(render_frame, m_spellCheck.data()); +#endif #if BUILDFLAG(ENABLE_BASIC_PRINTING) new printing::PrintWebViewHelper( render_frame, @@ -179,7 +185,7 @@ bool ContentRendererClientQt::ShouldSuppressErrorPage(content::RenderFrame *fram // To tap into the chromium localized strings. Ripped from the chrome layer (highly simplified). void ContentRendererClientQt::GetNavigationErrorStrings(content::RenderFrame* renderFrame, const blink::WebURLRequest &failedRequest, const blink::WebURLError &error, std::string *errorHtml, base::string16 *errorDescription) { - const bool isPost = QByteArray::fromStdString(failedRequest.httpMethod().utf8()) == QByteArrayLiteral("POST"); + const bool isPost = QByteArray::fromStdString(failedRequest.HttpMethod().Utf8()) == QByteArrayLiteral("POST"); if (errorHtml) { // Use a local error page. @@ -190,8 +196,8 @@ void ContentRendererClientQt::GetNavigationErrorStrings(content::RenderFrame* re // TODO(elproxy): We could potentially get better diagnostics here by first calling // NetErrorHelper::GetErrorStringsForDnsProbe, but that one is harder to untangle. - error_page::LocalizedError::GetStrings(error.reason, error.domain.utf8(), error.unreachableURL, isPost - , error.staleCopyInCache && !isPost, false, false, locale + error_page::LocalizedError::GetStrings(error.reason, error.domain.Utf8(), error.unreachable_url, isPost + , error.stale_copy_in_cache && !isPost, false, false, locale , std::unique_ptr<error_page::ErrorPageParams>(), &errorStrings); resourceId = IDR_NET_ERROR_HTML; @@ -204,7 +210,7 @@ void ContentRendererClientQt::GetNavigationErrorStrings(content::RenderFrame* re } if (errorDescription) - *errorDescription = error_page::LocalizedError::GetErrorDetails(error.domain.utf8(), error.reason, isPost); + *errorDescription = error_page::LocalizedError::GetErrorDetails(error.domain.Utf8(), error.reason, isPost); } unsigned long long ContentRendererClientQt::VisitedLinkHash(const char *canonicalUrl, size_t length) diff --git a/src/core/renderer/pepper/pepper_flash_renderer_host_qt.cpp b/src/core/renderer/pepper/pepper_flash_renderer_host_qt.cpp index ca3ef9dda..bac1d7c1f 100644 --- a/src/core/renderer/pepper/pepper_flash_renderer_host_qt.cpp +++ b/src/core/renderer/pepper/pepper_flash_renderer_host_qt.cpp @@ -48,7 +48,8 @@ #include <vector> #include "base/lazy_instance.h" -#include "base/metrics/histogram.h" +#include "base/macros.h" +#include "base/metrics/histogram_macros.h" #include "base/strings/string_util.h" #include "content/public/renderer/pepper_plugin_instance.h" #include "content/public/renderer/render_thread.h" @@ -137,8 +138,8 @@ enum FlashNavigateUsage { FLASH_NAVIGATE_USAGE_ENUM_COUNT }; -static base::LazyInstance<std::map<std::string, FlashNavigateUsage> > -g_rejected_headers = LAZY_INSTANCE_INITIALIZER; +static base::LazyInstance<std::map<std::string, FlashNavigateUsage>>:: + DestructorAtExit g_rejected_headers = LAZY_INSTANCE_INITIALIZER; bool IsSimpleHeader(const std::string& lower_case_header_name, const std::string& header_value) diff --git a/src/core/renderer/render_frame_observer_qt.cpp b/src/core/renderer/render_frame_observer_qt.cpp index 45d45c739..727bf5b92 100644 --- a/src/core/renderer/render_frame_observer_qt.cpp +++ b/src/core/renderer/render_frame_observer_qt.cpp @@ -64,7 +64,11 @@ RenderFrameObserverQt::~RenderFrameObserverQt() { } -#if defined(ENABLE_PLUGINS) +void RenderFrameObserverQt::OnDestruct() { + delete this; +} + +#if BUILDFLAG(ENABLE_PLUGINS) void RenderFrameObserverQt::DidCreatePepperPlugin(content::RendererPpapiHost* host) { host->GetPpapiHost()->AddHostFactoryFilter( diff --git a/src/core/renderer/render_frame_observer_qt.h b/src/core/renderer/render_frame_observer_qt.h index b74be5cd1..ac098a961 100644 --- a/src/core/renderer/render_frame_observer_qt.h +++ b/src/core/renderer/render_frame_observer_qt.h @@ -43,6 +43,7 @@ #include "base/compiler_specific.h" #include "content/public/renderer/render_frame_observer.h" #include "content/public/renderer/render_frame_observer_tracker.h" +#include "ppapi/features/features.h" namespace content { @@ -59,10 +60,10 @@ public: explicit RenderFrameObserverQt(content::RenderFrame* render_frame); ~RenderFrameObserverQt(); -#if defined(ENABLE_PLUGINS) +#if BUILDFLAG(ENABLE_PLUGINS) void DidCreatePepperPlugin(content::RendererPpapiHost* host) override; #endif - void OnDestruct() override { } + void OnDestruct() override; void FrameDetached() override; bool isFrameDetached() const; diff --git a/src/core/renderer/render_view_observer_qt.cpp b/src/core/renderer/render_view_observer_qt.cpp index 97485afad..4893a5188 100644 --- a/src/core/renderer/render_view_observer_qt.cpp +++ b/src/core/renderer/render_view_observer_qt.cpp @@ -62,25 +62,30 @@ RenderViewObserverQt::RenderViewObserverQt( void RenderViewObserverQt::onFetchDocumentMarkup(quint64 requestId) { blink::WebString markup; - if (render_view()->GetWebView()->mainFrame()->isWebLocalFrame()) - markup = blink::WebFrameContentDumper::dumpAsMarkup( - static_cast<blink::WebLocalFrame*>(render_view()->GetWebView()->mainFrame())); - Send(new RenderViewObserverHostQt_DidFetchDocumentMarkup(routing_id(), requestId, markup)); + if (render_view()->GetWebView()->MainFrame()->IsWebLocalFrame()) + markup = blink::WebFrameContentDumper::DumpAsMarkup( + static_cast<blink::WebLocalFrame*>(render_view()->GetWebView()->MainFrame())); + Send(new RenderViewObserverHostQt_DidFetchDocumentMarkup(routing_id(), requestId, markup.Utf16())); } void RenderViewObserverQt::onFetchDocumentInnerText(quint64 requestId) { blink::WebString text; - if (render_view()->GetWebView()->mainFrame()->isWebLocalFrame()) - text = blink::WebFrameContentDumper::dumpWebViewAsText( + if (render_view()->GetWebView()->MainFrame()->IsWebLocalFrame()) + text = blink::WebFrameContentDumper::DumpWebViewAsText( render_view()->GetWebView(), std::numeric_limits<std::size_t>::max()); - Send(new RenderViewObserverHostQt_DidFetchDocumentInnerText(routing_id(), requestId, text)); + Send(new RenderViewObserverHostQt_DidFetchDocumentInnerText(routing_id(), requestId, text.Utf16())); } void RenderViewObserverQt::onSetBackgroundColor(quint32 color) { - render_view()->GetWebFrameWidget()->setBaseBackgroundColor(color); + render_view()->GetWebFrameWidget()->SetBaseBackgroundColor(color); +} + +void RenderViewObserverQt::OnDestruct() +{ + delete this; } bool RenderViewObserverQt::OnMessageReceived(const IPC::Message& message) diff --git a/src/core/renderer/render_view_observer_qt.h b/src/core/renderer/render_view_observer_qt.h index 60b11c428..abb472f02 100644 --- a/src/core/renderer/render_view_observer_qt.h +++ b/src/core/renderer/render_view_observer_qt.h @@ -57,7 +57,7 @@ private: void onFetchDocumentInnerText(quint64 requestId); void onSetBackgroundColor(quint32 color); - void OnDestruct() override { } + void OnDestruct() override; bool OnMessageReceived(const IPC::Message& message) override; void Navigate(const GURL& url) override; diff --git a/src/core/renderer/user_resource_controller.cpp b/src/core/renderer/user_resource_controller.cpp index b172c762b..b4375dfdb 100644 --- a/src/core/renderer/user_resource_controller.cpp +++ b/src/core/renderer/user_resource_controller.cpp @@ -39,10 +39,12 @@ #include "user_resource_controller.h" +#include "base/memory/weak_ptr.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" +#include "content/public/renderer/render_frame_observer.h" #include "content/public/renderer/render_view_observer.h" #include "extensions/common/url_pattern.h" #include "third_party/WebKit/public/web/WebDocument.h" @@ -97,16 +99,19 @@ static bool scriptMatchesURL(const UserScriptData &scriptData, const GURL &url) return true; } -class UserResourceController::RenderViewObserverHelper : public content::RenderViewObserver +class UserResourceController::RenderFrameObserverHelper : public content::RenderFrameObserver { public: - RenderViewObserverHelper(content::RenderView *); + RenderFrameObserverHelper(content::RenderFrame* render_frame); + private: - // RenderViewObserver implementation. - void DidFinishDocumentLoad(blink::WebLocalFrame* frame) override; - void DidFinishLoad(blink::WebLocalFrame* frame) override; - void DidStartProvisionalLoad(blink::WebLocalFrame* frame) override; - void FrameDetached(blink::WebFrame* frame) override; + ~RenderFrameObserverHelper() override; + + // RenderFrameObserver implementation. + void DidFinishDocumentLoad() override; + void DidFinishLoad() override; + void DidStartProvisionalLoad(blink::WebDataSource* data_source) override; + void FrameDetached() override; void OnDestruct() override; bool OnMessageReceived(const IPC::Message& message) override; @@ -115,10 +120,24 @@ private: void onScriptsCleared(); void runScripts(UserScriptData::InjectionPoint, blink::WebLocalFrame *); + + // Set of frames which are pending to get an AfterLoad invocation of runScripts, if they + // haven't gotten it already. QSet<blink::WebLocalFrame *> m_pendingFrames; + base::WeakPtrFactory<RenderFrameObserverHelper> m_weakPtrFactory; +}; + +// Used only for script cleanup on RenderView destruction. +class UserResourceController::RenderViewObserverHelper : public content::RenderViewObserver +{ +public: + RenderViewObserverHelper(content::RenderView* render_view); +private: + // RenderViewObserver implementation. + void OnDestruct() override; }; -void UserResourceController::RenderViewObserverHelper::runScripts(UserScriptData::InjectionPoint p, blink::WebLocalFrame *frame) +void UserResourceController::RenderFrameObserverHelper::runScripts(UserScriptData::InjectionPoint p, blink::WebLocalFrame *frame) { if (p == UserScriptData::AfterLoad && !m_pendingFrames.remove(frame)) return; @@ -128,10 +147,11 @@ void UserResourceController::RenderViewObserverHelper::runScripts(UserScriptData void UserResourceController::runScripts(UserScriptData::InjectionPoint p, blink::WebLocalFrame *frame) { - content::RenderView *renderView = content::RenderView::FromWebView(frame->view()); - const bool isMainFrame = (frame == renderView->GetWebView()->mainFrame()); + content::RenderFrame *renderFrame = content::RenderFrame::FromWebFrame(frame); + content::RenderView *renderView = renderFrame->GetRenderView(); + const bool isMainFrame = renderFrame->IsMainFrame(); - QList<uint64_t> scriptsToRun = m_viewUserScriptMap.value(globalScriptsIndex).toList(); + QList<uint64_t> scriptsToRun = m_viewUserScriptMap.value(0).toList(); scriptsToRun.append(m_viewUserScriptMap.value(renderView).toList()); Q_FOREACH (uint64_t id, scriptsToRun) { @@ -139,13 +159,13 @@ void UserResourceController::runScripts(UserScriptData::InjectionPoint p, blink: if (script.injectionPoint != p || (!script.injectForSubframes && !isMainFrame)) continue; - if (!scriptMatchesURL(script, frame->document().url())) + if (!scriptMatchesURL(script, frame->GetDocument().Url())) continue; - blink::WebScriptSource source(blink::WebString::fromUTF8(script.source), script.url); + blink::WebScriptSource source(blink::WebString::FromUTF8(script.source), script.url); if (script.worldId) - frame->executeScriptInIsolatedWorld(script.worldId, &source, /*numSources = */1, /*contentScriptExtentsionGroup = */ 0); + frame->ExecuteScriptInIsolatedWorld(script.worldId, &source, /*numSources = */1, /*contentScriptExtentsionGroup = */ 0); else - frame->executeScript(source); + frame->ExecuteScript(source); } } @@ -159,67 +179,92 @@ void UserResourceController::RunScriptsAtDocumentEnd(content::RenderFrame *rende runScripts(UserScriptData::DocumentLoadFinished, render_frame->GetWebFrame()); } -UserResourceController::RenderViewObserverHelper::RenderViewObserverHelper(content::RenderView *renderView) - : content::RenderViewObserver(renderView) +UserResourceController::RenderFrameObserverHelper::RenderFrameObserverHelper(content::RenderFrame *render_frame) + : content::RenderFrameObserver(render_frame), m_weakPtrFactory(this) { } -void UserResourceController::RenderViewObserverHelper::DidFinishDocumentLoad(blink::WebLocalFrame *frame) +UserResourceController::RenderFrameObserverHelper::~RenderFrameObserverHelper() { + m_weakPtrFactory.InvalidateWeakPtrs(); +} + +UserResourceController::RenderViewObserverHelper::RenderViewObserverHelper(content::RenderView *render_view) + : content::RenderViewObserver(render_view) +{ +} + +void UserResourceController::RenderFrameObserverHelper::DidFinishDocumentLoad() +{ + blink::WebLocalFrame *frame = render_frame()->GetWebFrame(); m_pendingFrames.insert(frame); - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, base::Bind(&UserResourceController::RenderViewObserverHelper::runScripts, - base::Unretained(this), UserScriptData::AfterLoad, frame), + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, base::Bind(&UserResourceController::RenderFrameObserverHelper::runScripts, + m_weakPtrFactory.GetWeakPtr(), UserScriptData::AfterLoad, frame), base::TimeDelta::FromMilliseconds(afterLoadTimeout)); } -void UserResourceController::RenderViewObserverHelper::DidFinishLoad(blink::WebLocalFrame *frame) +void UserResourceController::RenderFrameObserverHelper::DidFinishLoad() { + blink::WebLocalFrame *frame = render_frame()->GetWebFrame(); + // DidFinishDocumentLoad always comes before this, so frame has already been marked as pending. - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(&UserResourceController::RenderViewObserverHelper::runScripts, - base::Unretained(this), UserScriptData::AfterLoad, frame)); + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, base::Bind(&UserResourceController::RenderFrameObserverHelper::runScripts, + m_weakPtrFactory.GetWeakPtr(), UserScriptData::AfterLoad, frame)); } -void UserResourceController::RenderViewObserverHelper::DidStartProvisionalLoad(blink::WebLocalFrame *frame) +void UserResourceController::RenderFrameObserverHelper::DidStartProvisionalLoad(blink::WebDataSource *data_source) { + Q_UNUSED(data_source); + blink::WebLocalFrame *frame = render_frame()->GetWebFrame(); m_pendingFrames.remove(frame); } -void UserResourceController::RenderViewObserverHelper::FrameDetached(blink::WebFrame *frame) +void UserResourceController::RenderFrameObserverHelper::FrameDetached() { - if (frame->isWebLocalFrame()) - m_pendingFrames.remove(frame->toWebLocalFrame()); + blink::WebLocalFrame *frame = render_frame()->GetWebFrame(); + m_pendingFrames.remove(frame); +} + +void UserResourceController::RenderFrameObserverHelper::OnDestruct() +{ + delete this; } void UserResourceController::RenderViewObserverHelper::OnDestruct() { + // Remove all scripts associated with the render view. UserResourceController::instance()->renderViewDestroyed(render_view()); + delete this; } -bool UserResourceController::RenderViewObserverHelper::OnMessageReceived(const IPC::Message &message) +bool UserResourceController::RenderFrameObserverHelper::OnMessageReceived(const IPC::Message &message) { bool handled = true; - IPC_BEGIN_MESSAGE_MAP(UserResourceController::RenderViewObserverHelper, message) - IPC_MESSAGE_HANDLER(RenderViewObserverHelper_AddScript, onUserScriptAdded) - IPC_MESSAGE_HANDLER(RenderViewObserverHelper_RemoveScript, onUserScriptRemoved) - IPC_MESSAGE_HANDLER(RenderViewObserverHelper_ClearScripts, onScriptsCleared) + IPC_BEGIN_MESSAGE_MAP(UserResourceController::RenderFrameObserverHelper, message) + IPC_MESSAGE_HANDLER(RenderFrameObserverHelper_AddScript, onUserScriptAdded) + IPC_MESSAGE_HANDLER(RenderFrameObserverHelper_RemoveScript, onUserScriptRemoved) + IPC_MESSAGE_HANDLER(RenderFrameObserverHelper_ClearScripts, onScriptsCleared) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; } -void UserResourceController::RenderViewObserverHelper::onUserScriptAdded(const UserScriptData &script) +void UserResourceController::RenderFrameObserverHelper::onUserScriptAdded(const UserScriptData &script) { - UserResourceController::instance()->addScriptForView(script, render_view()); + content::RenderView *view = render_frame()->GetRenderView(); + UserResourceController::instance()->addScriptForView(script, view); } -void UserResourceController::RenderViewObserverHelper::onUserScriptRemoved(const UserScriptData &script) +void UserResourceController::RenderFrameObserverHelper::onUserScriptRemoved(const UserScriptData &script) { - UserResourceController::instance()->removeScriptForView(script, render_view()); + content::RenderView *view = render_frame()->GetRenderView(); + UserResourceController::instance()->removeScriptForView(script, view); } -void UserResourceController::RenderViewObserverHelper::onScriptsCleared() +void UserResourceController::RenderFrameObserverHelper::onScriptsCleared() { - UserResourceController::instance()->clearScriptsForView(render_view()); + content::RenderView *view = render_frame()->GetRenderView(); + UserResourceController::instance()->clearScriptsForView(view); } UserResourceController *UserResourceController::instance() @@ -248,9 +293,15 @@ UserResourceController::UserResourceController() #endif // !defined(QT_NO_DEBUG) || defined(QT_FORCE_ASSERTS) } +void UserResourceController::renderFrameCreated(content::RenderFrame *renderFrame) +{ + // Will destroy itself when the RenderFrame is destroyed. + new RenderFrameObserverHelper(renderFrame); +} + void UserResourceController::renderViewCreated(content::RenderView *renderView) { - // Will destroy itself with their RenderView. + // Will destroy itself when the RenderView is destroyed. new RenderViewObserverHelper(renderView); } diff --git a/src/core/renderer/user_resource_controller.h b/src/core/renderer/user_resource_controller.h index 5d412fe40..50af24243 100644 --- a/src/core/renderer/user_resource_controller.h +++ b/src/core/renderer/user_resource_controller.h @@ -61,8 +61,9 @@ class UserResourceController : public content::RenderThreadObserver { public: static UserResourceController *instance(); UserResourceController(); + void renderFrameCreated(content::RenderFrame *); void renderViewCreated(content::RenderView *); - void renderViewDestroyed(content::RenderView *); + void renderViewDestroyed(content::RenderView *renderView); void addScriptForView(const UserScriptData &, content::RenderView *); void removeScriptForView(const UserScriptData &, content::RenderView *); void clearScriptsForView(content::RenderView *); @@ -73,6 +74,7 @@ public: private: Q_DISABLE_COPY(UserResourceController) + class RenderFrameObserverHelper; class RenderViewObserverHelper; // RenderProcessObserver implementation. @@ -89,7 +91,7 @@ private: ViewUserScriptMap m_viewUserScriptMap; QHash<uint64_t, UserScriptData> m_scripts; - friend class RenderViewObserverHelper; + friend class RenderFrameObserverHelper; }; #endif // USER_RESOURCE_CONTROLLER_H diff --git a/src/core/renderer/web_channel_ipc_transport.cpp b/src/core/renderer/web_channel_ipc_transport.cpp index 2420c4420..edd223223 100644 --- a/src/core/renderer/web_channel_ipc_transport.cpp +++ b/src/core/renderer/web_channel_ipc_transport.cpp @@ -68,25 +68,30 @@ private: WebChannelTransport() { } virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate *isolate) override; - void NativeQtSendMessage(gin::Arguments *args) + bool NativeQtSendMessage(gin::Arguments *args) { content::RenderView *renderView = GetRenderView(args->isolate()); if (!renderView || args->Length() != 1) - return; + return false; v8::Handle<v8::Value> val; args->GetNext(&val); if (!val->IsString() && !val->IsStringObject()) - return; + return false; v8::String::Utf8Value utf8(val->ToString()); QByteArray valueData(*utf8, utf8.length()); QJsonParseError error; QJsonDocument doc = QJsonDocument::fromJson(valueData, &error); - if (error.error != QJsonParseError::NoError) + if (error.error != QJsonParseError::NoError) { qWarning("%s %d: Parsing error: %s",__FILE__, __LINE__, qPrintable(error.errorString())); + return false; + } int size = 0; const char *rawData = doc.rawData(&size); + if (size == 0) + return false; renderView->Send(new WebChannelIPCTransportHost_SendMessage(renderView->GetRoutingID(), std::vector<char>(rawData, rawData + size))); + return true; } DISALLOW_COPY_AND_ASSIGN(WebChannelTransport); @@ -100,9 +105,9 @@ void WebChannelTransport::Install(blink::WebFrame *frame, uint worldId) v8::HandleScope handleScope(isolate); v8::Handle<v8::Context> context; if (worldId == 0) - context = frame->mainWorldScriptContext(); + context = frame->MainWorldScriptContext(); else - context = frame->toWebLocalFrame()->isolatedWorldScriptContext(worldId, 0); + context = frame->ToWebLocalFrame()->IsolatedWorldScriptContext(worldId); v8::Context::Scope contextScope(context); gin::Handle<WebChannelTransport> transport = gin::CreateHandle(isolate, new WebChannelTransport); @@ -121,9 +126,9 @@ void WebChannelTransport::Uninstall(blink::WebFrame *frame, uint worldId) v8::HandleScope handleScope(isolate); v8::Handle<v8::Context> context; if (worldId == 0) - context = frame->mainWorldScriptContext(); + context = frame->MainWorldScriptContext(); else - context = frame->toWebLocalFrame()->isolatedWorldScriptContext(worldId, 0); + context = frame->ToWebLocalFrame()->IsolatedWorldScriptContext(worldId); v8::Context::Scope contextScope(context); v8::Handle<v8::Object> global(context->Global()); @@ -140,12 +145,12 @@ gin::ObjectTemplateBuilder WebChannelTransport::GetObjectTemplateBuilder(v8::Iso content::RenderView *WebChannelTransport::GetRenderView(v8::Isolate *isolate) { - blink::WebLocalFrame *webframe = blink::WebLocalFrame::frameForContext(isolate->GetCurrentContext()); + blink::WebLocalFrame *webframe = blink::WebLocalFrame::FrameForContext(isolate->GetCurrentContext()); DCHECK(webframe) << "There should be an active frame since we just got a native function called."; if (!webframe) return 0; - blink::WebView *webview = webframe->view(); + blink::WebView *webview = webframe->View(); if (!webview) return 0; // can happen during closing @@ -174,7 +179,7 @@ void WebChannelIPCTransport::installWebChannel(uint worldId) blink::WebView *webView = render_view()->GetWebView(); if (!webView) return; - WebChannelTransport::Install(webView->mainFrame(), worldId); + WebChannelTransport::Install(webView->MainFrame(), worldId); m_installed = true; m_installedWorldId = worldId; } @@ -185,7 +190,7 @@ void WebChannelIPCTransport::uninstallWebChannel(uint worldId) blink::WebView *webView = render_view()->GetWebView(); if (!webView) return; - WebChannelTransport::Uninstall(webView->mainFrame(), worldId); + WebChannelTransport::Uninstall(webView->MainFrame(), worldId); m_installed = false; } @@ -201,12 +206,12 @@ void WebChannelIPCTransport::dispatchWebChannelMessage(const std::vector<char> & v8::Isolate *isolate = v8::Isolate::GetCurrent(); v8::HandleScope handleScope(isolate); - blink::WebFrame *frame = webView->mainFrame(); + blink::WebFrame *frame = webView->MainFrame(); v8::Handle<v8::Context> context; if (worldId == 0) - context = frame->mainWorldScriptContext(); + context = frame->MainWorldScriptContext(); else - context = frame->toWebLocalFrame()->isolatedWorldScriptContext(worldId, 0); + context = frame->ToWebLocalFrame()->IsolatedWorldScriptContext(worldId); v8::Context::Scope contextScope(context); v8::Handle<v8::Object> global(context->Global()); @@ -234,7 +239,7 @@ void WebChannelIPCTransport::dispatchWebChannelMessage(const std::vector<char> & const int argc = 1; v8::Handle<v8::Value> argv[argc]; argv[0] = messageObject; - frame->callFunctionEvenIfScriptDisabled(callback, webChannelObjectValue->ToObject(), argc, argv); + frame->CallFunctionEvenIfScriptDisabled(callback, webChannelObjectValue->ToObject(), argc, argv); } bool WebChannelIPCTransport::OnMessageReceived(const IPC::Message &message) @@ -249,4 +254,9 @@ bool WebChannelIPCTransport::OnMessageReceived(const IPC::Message &message) return handled; } +void WebChannelIPCTransport::OnDestruct() +{ + delete this; +} + } // namespace diff --git a/src/core/renderer/web_channel_ipc_transport.h b/src/core/renderer/web_channel_ipc_transport.h index a2c7d5b4e..04041c6c7 100644 --- a/src/core/renderer/web_channel_ipc_transport.h +++ b/src/core/renderer/web_channel_ipc_transport.h @@ -71,7 +71,7 @@ private: // content::RenderViewObserver overrides: bool OnMessageReceived(const IPC::Message &message) override; - void OnDestruct() override { } + void OnDestruct() override; bool m_installed; uint m_installedWorldId; diff --git a/src/core/renderer_host/user_resource_controller_host.cpp b/src/core/renderer_host/user_resource_controller_host.cpp index cf0cbd357..2799d5d85 100644 --- a/src/core/renderer_host/user_resource_controller_host.cpp +++ b/src/core/renderer_host/user_resource_controller_host.cpp @@ -47,6 +47,7 @@ #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host_observer.h" #include "content/public/browser/render_view_host.h" +#include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" @@ -57,8 +58,9 @@ public: WebContentsObserverHelper(UserResourceControllerHost *, content::WebContents *); // WebContentsObserver overrides: - void RenderViewCreated(content::RenderViewHost *renderViewHost) override; - void RenderViewHostChanged(content::RenderViewHost *oldHost, content::RenderViewHost *newHost) override; + void RenderFrameCreated(content::RenderFrameHost *renderFrameHost) override; + void RenderFrameHostChanged(content::RenderFrameHost *oldHost, + content::RenderFrameHost *newHost) override; void WebContentsDestroyed() override; private: @@ -71,18 +73,21 @@ UserResourceControllerHost::WebContentsObserverHelper::WebContentsObserverHelper { } -void UserResourceControllerHost::WebContentsObserverHelper::RenderViewCreated(content::RenderViewHost *renderViewHost) +void UserResourceControllerHost::WebContentsObserverHelper::RenderFrameCreated( + content::RenderFrameHost *renderFrameHost) { content::WebContents *contents = web_contents(); Q_FOREACH (const UserScript &script, m_controllerHost->m_perContentsScripts.value(contents)) - renderViewHost->Send(new RenderViewObserverHelper_AddScript(renderViewHost->GetRoutingID(), script.data())); + renderFrameHost->Send(new RenderFrameObserverHelper_AddScript( + renderFrameHost->GetRoutingID(), script.data())); } -void UserResourceControllerHost::WebContentsObserverHelper::RenderViewHostChanged(content::RenderViewHost *oldHost, - content::RenderViewHost */*newHost*/) +void UserResourceControllerHost::WebContentsObserverHelper::RenderFrameHostChanged( + content::RenderFrameHost *oldHost, + content::RenderFrameHost *newHost) { if (oldHost) - oldHost->Send(new RenderViewObserverHelper_ClearScripts(oldHost->GetRoutingID())); + oldHost->Send(new RenderFrameObserverHelper_ClearScripts(oldHost->GetRoutingID())); } void UserResourceControllerHost::WebContentsObserverHelper::WebContentsDestroyed() @@ -115,7 +120,8 @@ void UserResourceControllerHost::addUserScript(const UserScript &script, WebCont if (script.isNull()) return; // Global scripts should be dispatched to all our render processes. - if (!adapter) { + const bool isProfileWideScript = !adapter; + if (isProfileWideScript) { if (!m_profileWideScripts.contains(script)) { m_profileWideScripts.append(script); Q_FOREACH (content::RenderProcessHost *renderer, m_observedProcesses) @@ -136,7 +142,9 @@ void UserResourceControllerHost::addUserScript(const UserScript &script, WebCont m_perContentsScripts.insert(contents, currentScripts); } } - contents->Send(new RenderViewObserverHelper_AddScript(contents->GetRoutingID(), script.data())); + contents->Send(new RenderFrameObserverHelper_AddScript(contents->GetRenderViewHost()-> + GetMainFrame()->GetRoutingID(), + script.data())); } } @@ -145,7 +153,8 @@ bool UserResourceControllerHost::containsUserScript(const UserScript &script, We if (script.isNull()) return false; // Global scripts should be dispatched to all our render processes. - if (!adapter) + const bool isProfileWideScript = !adapter; + if (isProfileWideScript) return m_profileWideScripts.contains(script); return m_perContentsScripts.value(adapter->webContents()).contains(script); } @@ -154,7 +163,8 @@ bool UserResourceControllerHost::removeUserScript(const UserScript &script, WebC { if (script.isNull()) return false; - if (!adapter) { + const bool isProfileWideScript = !adapter; + if (isProfileWideScript) { QList<UserScript>::iterator it = std::find(m_profileWideScripts.begin(), m_profileWideScripts.end(), script); if (it == m_profileWideScripts.end()) @@ -170,7 +180,9 @@ bool UserResourceControllerHost::removeUserScript(const UserScript &script, WebC QList<UserScript>::iterator it = std::find(list.begin(), list.end(), script); if (it == list.end()) return false; - contents->Send(new RenderViewObserverHelper_RemoveScript(contents->GetRoutingID(), (*it).data())); + contents->Send(new RenderFrameObserverHelper_RemoveScript(contents-> + GetMainFrame()->GetRoutingID(), + (*it).data())); list.erase(it); } return true; @@ -178,27 +190,31 @@ bool UserResourceControllerHost::removeUserScript(const UserScript &script, WebC void UserResourceControllerHost::clearAllScripts(WebContentsAdapter *adapter) { - if (!adapter) { + const bool isProfileWideScript = !adapter; + if (isProfileWideScript) { m_profileWideScripts.clear(); Q_FOREACH (content::RenderProcessHost *renderer, m_observedProcesses) renderer->Send(new UserResourceController_ClearScripts); } else { content::WebContents *contents = adapter->webContents(); m_perContentsScripts.remove(contents); - contents->Send(new RenderViewObserverHelper_ClearScripts(contents->GetRoutingID())); + contents->Send(new RenderFrameObserverHelper_ClearScripts(contents-> + GetMainFrame()->GetRoutingID())); } } const QList<UserScript> UserResourceControllerHost::registeredScripts(WebContentsAdapter *adapter) const { - if (!adapter) + const bool isProfileWideScript = !adapter; + if (isProfileWideScript) return m_profileWideScripts; return m_perContentsScripts.value(adapter->webContents()); } void UserResourceControllerHost::reserve(WebContentsAdapter *adapter, int count) { - if (!adapter) + const bool isProfileWideScript = !adapter; + if (isProfileWideScript) m_profileWideScripts.reserve(count); else m_perContentsScripts[adapter->webContents()].reserve(count); diff --git a/src/core/renderer_host/web_channel_ipc_transport_host.cpp b/src/core/renderer_host/web_channel_ipc_transport_host.cpp index a093632bc..c47b255b7 100644 --- a/src/core/renderer_host/web_channel_ipc_transport_host.cpp +++ b/src/core/renderer_host/web_channel_ipc_transport_host.cpp @@ -93,6 +93,7 @@ void WebChannelIPCTransportHost::sendMessage(const QJsonObject &message) void WebChannelIPCTransportHost::onWebChannelMessage(const std::vector<char> &message) { + Q_ASSERT(!message.empty()); QJsonDocument doc = QJsonDocument::fromRawData(message.data(), message.size(), QJsonDocument::BypassValidation); Q_ASSERT(doc.isObject()); Q_EMIT messageReceived(doc.object(), this); diff --git a/src/core/resource_bundle_qt.cpp b/src/core/resource_bundle_qt.cpp index cc3c1de06..c37854ea6 100644 --- a/src/core/resource_bundle_qt.cpp +++ b/src/core/resource_bundle_qt.cpp @@ -38,7 +38,7 @@ ****************************************************************************/ #include "base/command_line.h" -#include "base/metrics/histogram.h" +#include "base/metrics/histogram_macros.h" #include "content/public/common/content_switches.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/data_pack.h" diff --git a/src/core/surface_factory_qt.cpp b/src/core/surface_factory_qt.cpp index e8be84807..6e5e13866 100644 --- a/src/core/surface_factory_qt.cpp +++ b/src/core/surface_factory_qt.cpp @@ -44,7 +44,12 @@ #include "base/files/file_path.h" #include "base/native_library.h" +#include "ui/gl/gl_context_egl.h" #include "ui/gl/gl_implementation.h" +#include "ui/gl/gl_surface.h" +#include "ui/gl/init/gl_initializer.h" +#include "ui/gl/init/gl_factory.h" +#include "ui/ozone/common/gl_ozone_egl.h" #include <QGuiApplication> @@ -55,7 +60,38 @@ namespace QtWebEngineCore { -bool SurfaceFactoryQt::LoadEGLGLES2Bindings() +class GLOzoneQt : public ui::GLOzoneEGL { +public: + scoped_refptr<gl::GLSurface> CreateViewGLSurface(gfx::AcceleratedWidget /*window*/) override + { + return nullptr; + } + scoped_refptr<gl::GLSurface> CreateOffscreenGLSurface(const gfx::Size& /*size*/) override + { + return nullptr; + } + +protected: + // Returns native platform display handle. This is used to obtain the EGL + // display connection for the native display. + intptr_t GetNativeDisplay() override; + + // Sets up GL bindings for the native surface. + bool LoadGLES2Bindings() override; + +}; + +base::NativeLibrary LoadLibrary(const base::FilePath& filename) { + base::NativeLibraryLoadError error; + base::NativeLibrary library = base::LoadNativeLibrary(filename, &error); + if (!library) { + LOG(ERROR) << "Failed to load " << filename.MaybeAsASCII() << ": " << error.ToString(); + return NULL; + } + return library; +} + +bool GLOzoneQt::LoadGLES2Bindings() { base::NativeLibrary eglgles2Library = dlopen(NULL, RTLD_LAZY); if (!eglgles2Library) { @@ -75,7 +111,7 @@ bool SurfaceFactoryQt::LoadEGLGLES2Bindings() return true; } -intptr_t SurfaceFactoryQt::GetNativeDisplay() +intptr_t GLOzoneQt::GetNativeDisplay() { static void *display = GLContextHelper::getNativeDisplay(); @@ -85,6 +121,18 @@ intptr_t SurfaceFactoryQt::GetNativeDisplay() return reinterpret_cast<intptr_t>(EGL_DEFAULT_DISPLAY); } +std::vector<gl::GLImplementation> SurfaceFactoryQt::GetAllowedGLImplementations() +{ + std::vector<gl::GLImplementation> impls; + impls.push_back(gl::kGLImplementationEGLGLES2); + return impls; +} + +ui::GLOzone* SurfaceFactoryQt::GetGLOzone(gl::GLImplementation implementation) +{ + return new GLOzoneQt(); +} + } // namespace QtWebEngineCore #endif // defined(USE_OZONE) diff --git a/src/core/surface_factory_qt.h b/src/core/surface_factory_qt.h index 76b6dc6ed..b7991829c 100644 --- a/src/core/surface_factory_qt.h +++ b/src/core/surface_factory_qt.h @@ -46,11 +46,10 @@ namespace QtWebEngineCore { -class SurfaceFactoryQt - : public ui::SurfaceFactoryOzone +class SurfaceFactoryQt : public ui::SurfaceFactoryOzone { - bool LoadEGLGLES2Bindings() override; - intptr_t GetNativeDisplay() override; + std::vector<gl::GLImplementation> GetAllowedGLImplementations() override; + ui::GLOzone* GetGLOzone(gl::GLImplementation implementation) override; }; } // namespace QtWebEngineCore diff --git a/src/core/url_request_context_getter_qt.cpp b/src/core/url_request_context_getter_qt.cpp index 1f3d6fcbe..8a6717e91 100644 --- a/src/core/url_request_context_getter_qt.cpp +++ b/src/core/url_request_context_getter_qt.cpp @@ -189,9 +189,9 @@ void URLRequestContextGetterQt::cancelAllUrlRequests() Q_ASSERT(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); Q_ASSERT(m_urlRequestContext); - std::set<const net::URLRequest*>* url_requests = m_urlRequestContext->url_requests(); - std::set<const net::URLRequest*>::const_iterator it = url_requests->begin(); - std::set<const net::URLRequest*>::const_iterator end = url_requests->end(); + const std::set<const net::URLRequest*>& url_requests = m_urlRequestContext->url_requests(); + std::set<const net::URLRequest*>::const_iterator it = url_requests.begin(); + std::set<const net::URLRequest*>::const_iterator end = url_requests.end(); for ( ; it != end; ++it) { net::URLRequest* request = const_cast<net::URLRequest*>(*it); if (request) @@ -295,8 +295,7 @@ void URLRequestContextGetterQt::generateCookieStore() m_storage->set_channel_id_service( base::WrapUnique(new net::ChannelIDService( - new net::DefaultChannelIDStore(channel_id_db.get()), - base::WorkerPool::GetTaskRunner(true)))); + new net::DefaultChannelIDStore(channel_id_db.get())))); // Unset it first to get a chance to destroy and flush the old cookie store before opening a new on possibly the same file. m_storage->set_cookie_store(0); @@ -572,10 +571,11 @@ void URLRequestContextGetterQt::generateJobFactory() // Set up interceptors in the reverse order. std::unique_ptr<net::URLRequestJobFactory> topJobFactory = std::move(jobFactory); - for (content::URLRequestInterceptorScopedVector::reverse_iterator i = m_requestInterceptors.rbegin(); i != m_requestInterceptors.rend(); ++i) - topJobFactory.reset(new net::URLRequestInterceptingJobFactory(std::move(topJobFactory), std::unique_ptr<net::URLRequestInterceptor>(*i))); + for (content::URLRequestInterceptorScopedVector::reverse_iterator i = m_requestInterceptors.rbegin(); i != m_requestInterceptors.rend(); ++i) { + topJobFactory.reset(new net::URLRequestInterceptingJobFactory(std::move(topJobFactory), std::move(*i))); + } - m_requestInterceptors.weak_clear(); + m_requestInterceptors.clear(); m_jobFactory = std::move(topJobFactory); diff --git a/src/core/url_request_custom_job.cpp b/src/core/url_request_custom_job.cpp index d093efd0a..47c9b3b4c 100644 --- a/src/core/url_request_custom_job.cpp +++ b/src/core/url_request_custom_job.cpp @@ -38,69 +38,63 @@ ****************************************************************************/ #include "url_request_custom_job.h" -#include "url_request_custom_job_delegate.h" - -#include "api/qwebengineurlrequestjob.h" -#include "api/qwebengineurlschemehandler.h" -#include "browser_context_adapter.h" -#include "type_conversion.h" - +#include "url_request_custom_job_proxy.h" #include "content/public/browser/browser_thread.h" -#include "net/base/net_errors.h" #include "net/base/io_buffer.h" -#include <QFileInfo> -#include <QMimeDatabase> -#include <QMimeType> -#include <QUrl> +#include <QIODevice> using namespace net; namespace QtWebEngineCore { -URLRequestCustomJob::URLRequestCustomJob(URLRequest *request, NetworkDelegate *networkDelegate, - const std::string &scheme, QWeakPointer<const BrowserContextAdapter> adapter) +URLRequestCustomJob::URLRequestCustomJob(URLRequest *request, + NetworkDelegate *networkDelegate, + const std::string &scheme, + QWeakPointer<const BrowserContextAdapter> adapter) : URLRequestJob(request, networkDelegate) - , m_scheme(scheme) - , m_adapter(adapter) - , m_shared(new URLRequestCustomJobShared(this)) + , m_proxy(new URLRequestCustomJobProxy(this, scheme, adapter)) + , m_device(nullptr) + , m_error(0) { } URLRequestCustomJob::~URLRequestCustomJob() { - if (m_shared) - m_shared->killJob(); -} - -static void startAsync(URLRequestCustomJobShared *shared) -{ - shared->startAsync(); + m_proxy->m_job = nullptr; + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + base::Bind(&URLRequestCustomJobProxy::release, + m_proxy)); + if (m_device && m_device->isOpen()) + m_device->close(); + m_device = nullptr; } void URLRequestCustomJob::Start() { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, base::Bind(&startAsync, m_shared)); + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + base::Bind(&URLRequestCustomJobProxy::initialize, + m_proxy, request()->url(), request()->method())); } void URLRequestCustomJob::Kill() { - if (m_shared) - m_shared->killJob(); - m_shared = 0; - + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + if (m_device && m_device->isOpen()) + m_device->close(); + m_device = nullptr; + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + base::Bind(&URLRequestCustomJobProxy::release, + m_proxy)); URLRequestJob::Kill(); } bool URLRequestCustomJob::GetMimeType(std::string *mimeType) const { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - if (!m_shared) - return false; - QMutexLocker lock(&m_shared->m_mutex); - if (m_shared->m_mimeType.size() > 0) { - *mimeType = m_shared->m_mimeType; + if (m_mimeType.size() > 0) { + *mimeType = m_mimeType; return true; } return false; @@ -109,11 +103,8 @@ bool URLRequestCustomJob::GetMimeType(std::string *mimeType) const bool URLRequestCustomJob::GetCharset(std::string* charset) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - if (!m_shared) - return false; - QMutexLocker lock(&m_shared->m_mutex); - if (m_shared->m_charset.size() > 0) { - *charset = m_shared->m_charset; + if (m_charset.size() > 0) { + *charset = m_charset; return true; } return false; @@ -122,11 +113,8 @@ bool URLRequestCustomJob::GetCharset(std::string* charset) bool URLRequestCustomJob::IsRedirectResponse(GURL* location, int* http_status_code) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - if (!m_shared) - return false; - QMutexLocker lock(&m_shared->m_mutex); - if (m_shared->m_redirect.is_valid()) { - *location = m_shared->m_redirect; + if (m_redirect.is_valid()) { + *location = m_redirect; *http_status_code = 303; return true; } @@ -136,224 +124,16 @@ bool URLRequestCustomJob::IsRedirectResponse(GURL* location, int* http_status_co int URLRequestCustomJob::ReadRawData(IOBuffer *buf, int bufSize) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - Q_ASSERT(m_shared); - QMutexLocker lock(&m_shared->m_mutex); - if (m_shared->m_error) - return m_shared->m_error; - qint64 rv = m_shared->m_device ? m_shared->m_device->read(buf->data(), bufSize) : -1; - if (rv >= 0) + if (m_error) + return m_error; + qint64 rv = m_device ? m_device->read(buf->data(), bufSize) : -1; + if (rv >= 0) { return static_cast<int>(rv); - else { + } else { // QIODevice::read might have called fail on us. - if (m_shared->m_error) - return m_shared->m_error; + if (m_error) + return m_error; return ERR_FAILED; } } - - -URLRequestCustomJobShared::URLRequestCustomJobShared(URLRequestCustomJob *job) - : m_mutex(QMutex::Recursive) - , m_job(job) - , m_delegate(0) - , m_error(0) - , m_started(false) - , m_asyncInitialized(false) - , m_weakFactory(this) -{ -} - -URLRequestCustomJobShared::~URLRequestCustomJobShared() -{ - Q_ASSERT(!m_job); - Q_ASSERT(!m_delegate); -} - -void URLRequestCustomJobShared::killJob() -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - QMutexLocker lock(&m_mutex); - m_job = 0; - bool doDelete = false; - if (m_delegate) { - m_delegate->deleteLater(); - } else { - // Do not delete yet if startAsync has not yet run. - doDelete = m_asyncInitialized; - } - if (m_device && m_device->isOpen()) - m_device->close(); - m_device = 0; - m_weakFactory.InvalidateWeakPtrs(); - lock.unlock(); - if (doDelete) - delete this; -} - -void URLRequestCustomJobShared::unsetJobDelegate() -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - QMutexLocker lock(&m_mutex); - m_delegate = 0; - bool doDelete = false; - if (m_job) - abort(); - else - doDelete = true; - lock.unlock(); - if (doDelete) - delete this; -} - -void URLRequestCustomJobShared::setReplyMimeType(const std::string &mimeType) -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - QMutexLocker lock(&m_mutex); - m_mimeType = mimeType; -} - -void URLRequestCustomJobShared::setReplyCharset(const std::string &charset) -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - QMutexLocker lock(&m_mutex); - m_charset = charset; -} - -void URLRequestCustomJobShared::setReplyDevice(QIODevice *device) -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - QMutexLocker lock(&m_mutex); - if (!m_job) - return; - m_device = device; - if (m_device && !m_device->isReadable()) - m_device->open(QIODevice::ReadOnly); - - qint64 size = m_device ? m_device->size() : -1; - if (size > 0) - m_job->set_expected_content_size(size); - if (m_device && m_device->isReadable()) - content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJobShared::notifyStarted, m_weakFactory.GetWeakPtr())); - else - fail(ERR_INVALID_URL); -} - -void URLRequestCustomJobShared::redirect(const GURL &url) -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - QMutexLocker lock(&m_mutex); - if (m_device || m_error) - return; - if (!m_job) - return; - m_redirect = url; - content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJobShared::notifyStarted, m_weakFactory.GetWeakPtr())); -} - -void URLRequestCustomJobShared::abort() -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - QMutexLocker lock(&m_mutex); - if (m_device && m_device->isOpen()) - m_device->close(); - m_device = 0; - if (!m_job) - return; - content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJobShared::notifyCanceled, m_weakFactory.GetWeakPtr())); -} - -void URLRequestCustomJobShared::notifyCanceled() -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - QMutexLocker lock(&m_mutex); - if (!m_job) - return; - if (m_started) - m_job->NotifyCanceled(); - else - m_job->NotifyStartError(URLRequestStatus(URLRequestStatus::CANCELED, ERR_ABORTED)); -} - -void URLRequestCustomJobShared::notifyStarted() -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - QMutexLocker lock(&m_mutex); - if (!m_job) - return; - Q_ASSERT(!m_started); - m_started = true; - m_job->NotifyHeadersComplete(); -} - -void URLRequestCustomJobShared::fail(int error) -{ - QMutexLocker lock(&m_mutex); - m_error = error; - if (content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) - return; - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (!m_job) - return; - content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, base::Bind(&URLRequestCustomJobShared::notifyFailure, m_weakFactory.GetWeakPtr())); -} - -void URLRequestCustomJobShared::notifyFailure() -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - QMutexLocker lock(&m_mutex); - if (!m_job) - return; - if (m_device) - m_device->close(); - if (!m_started) - m_job->NotifyStartError(URLRequestStatus::FromError(m_error)); - // else we fail on the next read, or the read that might already be in progress -} - -GURL URLRequestCustomJobShared::requestUrl() -{ - QMutexLocker lock(&m_mutex); - if (!m_job) - return GURL(); - return m_job->request()->url(); -} - -std::string URLRequestCustomJobShared::requestMethod() -{ - QMutexLocker lock(&m_mutex); - if (!m_job) - return std::string(); - return m_job->request()->method(); -} - -void URLRequestCustomJobShared::startAsync() -{ - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - Q_ASSERT(!m_started); - Q_ASSERT(!m_delegate); - QMutexLocker lock(&m_mutex); - if (!m_job) { - lock.unlock(); - delete this; - return; - } - - QWebEngineUrlSchemeHandler *schemeHandler = 0; - QSharedPointer<const BrowserContextAdapter> browserContext = m_job->m_adapter.toStrongRef(); - if (browserContext) - schemeHandler = browserContext->customUrlSchemeHandlers()[toQByteArray(m_job->m_scheme)]; - if (schemeHandler) { - m_delegate = new URLRequestCustomJobDelegate(this); - m_asyncInitialized = true; - QWebEngineUrlRequestJob *requestJob = new QWebEngineUrlRequestJob(m_delegate); - schemeHandler->requestStarted(requestJob); - } else { - lock.unlock(); - abort(); - delete this; - return; - } -} - } // namespace diff --git a/src/core/url_request_custom_job.h b/src/core/url_request_custom_job.h index 93edb0b8c..68a834d48 100644 --- a/src/core/url_request_custom_job.h +++ b/src/core/url_request_custom_job.h @@ -40,11 +40,9 @@ #ifndef URL_REQUEST_CUSTOM_JOB_H_ #define URL_REQUEST_CUSTOM_JOB_H_ -#include "net/url_request/url_request.h" #include "net/url_request/url_request_job.h" - -#include <QtCore/QMutex> -#include <QtCore/QPointer> +#include "url/gurl.h" +#include <QtCore/QWeakPointer> QT_FORWARD_DECLARE_CLASS(QIODevice) @@ -52,12 +50,15 @@ namespace QtWebEngineCore { class BrowserContextAdapter; class URLRequestCustomJobDelegate; -class URLRequestCustomJobShared; +class URLRequestCustomJobProxy; // A request job that handles reading custom URL schemes class URLRequestCustomJob : public net::URLRequestJob { public: - URLRequestCustomJob(net::URLRequest *request, net::NetworkDelegate *networkDelegate, const std::string &scheme, QWeakPointer<const BrowserContextAdapter> adapter); + URLRequestCustomJob(net::URLRequest *request, + net::NetworkDelegate *networkDelegate, + const std::string &scheme, + QWeakPointer<const BrowserContextAdapter> adapter); void Start() override; void Kill() override; int ReadRawData(net::IOBuffer *buf, int buf_size) override; @@ -69,54 +70,17 @@ protected: virtual ~URLRequestCustomJob(); private: - std::string m_scheme; - QWeakPointer<const BrowserContextAdapter> m_adapter; - URLRequestCustomJobShared *m_shared; - - friend class URLRequestCustomJobShared; - - DISALLOW_COPY_AND_ASSIGN(URLRequestCustomJob); -}; - -// A shared state between URLRequestCustomJob living on the IO thread -// and URLRequestCustomJobDelegate living on the UI thread. -class URLRequestCustomJobShared { -public: - URLRequestCustomJobShared(URLRequestCustomJob *job); - ~URLRequestCustomJobShared(); - - void setReplyMimeType(const std::string &); - void setReplyCharset(const std::string &); - void setReplyDevice(QIODevice *); - - void redirect(const GURL &url); - void fail(int); - void abort(); - - void killJob(); - void unsetJobDelegate(); - - void startAsync(); - void notifyStarted(); - void notifyFailure(); - void notifyCanceled(); - - GURL requestUrl(); - std::string requestMethod(); - - QMutex m_mutex; - QPointer<QIODevice> m_device; - URLRequestCustomJob *m_job; - URLRequestCustomJobDelegate *m_delegate; + scoped_refptr<URLRequestCustomJobProxy> m_proxy; std::string m_mimeType; std::string m_charset; - int m_error; GURL m_redirect; - bool m_started; - bool m_asyncInitialized; - base::WeakPtrFactory<URLRequestCustomJobShared> m_weakFactory; -}; + QIODevice *m_device; + int m_error; + + friend class URLRequestCustomJobProxy; + DISALLOW_COPY_AND_ASSIGN(URLRequestCustomJob); +}; } // namespace QtWebEngineCore #endif // URL_REQUEST_CUSTOM_JOB_H_ diff --git a/src/core/url_request_custom_job_delegate.cpp b/src/core/url_request_custom_job_delegate.cpp index 7e806a4e0..14de9a812 100644 --- a/src/core/url_request_custom_job_delegate.cpp +++ b/src/core/url_request_custom_job_delegate.cpp @@ -37,50 +37,59 @@ ** ****************************************************************************/ -#include "url_request_custom_job.h" #include "url_request_custom_job_delegate.h" +#include "url_request_custom_job_proxy.h" #include "type_conversion.h" #include "net/base/net_errors.h" +#include "content/public/browser/browser_thread.h" #include <QByteArray> namespace QtWebEngineCore { -URLRequestCustomJobDelegate::URLRequestCustomJobDelegate(URLRequestCustomJobShared *shared) - : m_shared(shared) +URLRequestCustomJobDelegate::URLRequestCustomJobDelegate(URLRequestCustomJobProxy *proxy, + const QUrl &url, + const QByteArray &method) + : m_proxy(proxy), + m_request(url), + m_method(method) { } URLRequestCustomJobDelegate::~URLRequestCustomJobDelegate() { - m_shared->unsetJobDelegate(); } QUrl URLRequestCustomJobDelegate::url() const { - return toQt(m_shared->requestUrl()); + return m_request; } QByteArray URLRequestCustomJobDelegate::method() const { - return QByteArray::fromStdString(m_shared->requestMethod()); + return m_method; } -void URLRequestCustomJobDelegate::setReply(const QByteArray &contentType, QIODevice *device) +void URLRequestCustomJobDelegate::reply(const QByteArray &contentType, QIODevice *device) { - m_shared->setReplyMimeType(contentType.toStdString()); - m_shared->setReplyDevice(device); + content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, + base::Bind(&URLRequestCustomJobProxy::reply, + m_proxy,contentType.toStdString(),device)); } void URLRequestCustomJobDelegate::abort() { - m_shared->abort(); + content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, + base::Bind(&URLRequestCustomJobProxy::abort, + m_proxy)); } void URLRequestCustomJobDelegate::redirect(const QUrl &url) { - m_shared->redirect(toGurl(url)); + content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, + base::Bind(&URLRequestCustomJobProxy::redirect, + m_proxy, toGurl(url))); } void URLRequestCustomJobDelegate::fail(Error error) @@ -105,8 +114,11 @@ void URLRequestCustomJobDelegate::fail(Error error) net_error = net::ERR_FAILED; break; } - if (net_error) - m_shared->fail(net_error); + if (net_error) { + content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, + base::Bind(&URLRequestCustomJobProxy::fail, + m_proxy, net_error)); + } } } // namespace diff --git a/src/core/url_request_custom_job_delegate.h b/src/core/url_request_custom_job_delegate.h index 7752d979e..eb99f3576 100644 --- a/src/core/url_request_custom_job_delegate.h +++ b/src/core/url_request_custom_job_delegate.h @@ -40,6 +40,7 @@ #ifndef URL_REQUEST_CUSTOM_JOB_DELEGATE_H_ #define URL_REQUEST_CUSTOM_JOB_DELEGATE_H_ +#include "base/memory/ref_counted.h" #include "qtwebenginecoreglobal.h" #include <QObject> @@ -49,7 +50,7 @@ QT_FORWARD_DECLARE_CLASS(QIODevice) namespace QtWebEngineCore { -class URLRequestCustomJobShared; +class URLRequestCustomJobProxy; class QWEBENGINE_EXPORT URLRequestCustomJobDelegate : public QObject { Q_OBJECT @@ -68,17 +69,20 @@ public: QUrl url() const; QByteArray method() const; - void setReply(const QByteArray &contentType, QIODevice *device); + void reply(const QByteArray &contentType, QIODevice *device); void redirect(const QUrl& url); void abort(); - void fail(Error); private: - URLRequestCustomJobDelegate(URLRequestCustomJobShared *shared); + URLRequestCustomJobDelegate(URLRequestCustomJobProxy *proxy, + const QUrl &url, + const QByteArray &method); - friend class URLRequestCustomJobShared; - URLRequestCustomJobShared *m_shared; + friend class URLRequestCustomJobProxy; + scoped_refptr<URLRequestCustomJobProxy> m_proxy; + QUrl m_request; + QByteArray m_method; }; } // namespace diff --git a/src/core/url_request_custom_job_proxy.cpp b/src/core/url_request_custom_job_proxy.cpp new file mode 100644 index 000000000..d53602c85 --- /dev/null +++ b/src/core/url_request_custom_job_proxy.cpp @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** 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 "url_request_custom_job_proxy.h" +#include "url_request_custom_job.h" +#include "url_request_custom_job_delegate.h" +#include "api/qwebengineurlrequestjob.h" +#include "browser_context_adapter.h" +#include "type_conversion.h" +#include "content/public/browser/browser_thread.h" + +using namespace net; + +namespace QtWebEngineCore { + +URLRequestCustomJobProxy::URLRequestCustomJobProxy(URLRequestCustomJob *job, + const std::string &scheme, + QWeakPointer<const BrowserContextAdapter> adapter) + : m_job(job) + , m_started(false) + , m_scheme(scheme) + , m_delegate(nullptr) + , m_adapter(adapter) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); +} + +URLRequestCustomJobProxy::~URLRequestCustomJobProxy() +{ +} + +void URLRequestCustomJobProxy::release() +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + if (m_delegate) { + m_delegate->deleteLater(); + m_delegate = nullptr; + } +} + +// Fix me: this is never used +/* +void URLRequestCustomJobProxy::setReplyCharset(const std::string &charset) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + if (!m_job) + return; + m_job->m_charset = charset; +} +*/ +void URLRequestCustomJobProxy::reply(std::string mimeType, QIODevice *device) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + if (!m_job) + return; + m_job->m_mimeType = mimeType; + m_job->m_device = device; + if (m_job->m_device && !m_job->m_device->isReadable()) + m_job->m_device->open(QIODevice::ReadOnly); + + qint64 size = m_job->m_device ? m_job->m_device->size() : -1; + if (size > 0) + m_job->set_expected_content_size(size); + if (m_job->m_device && m_job->m_device->isReadable()) { + m_started = true; + m_job->NotifyHeadersComplete(); + } else { + fail(ERR_INVALID_URL); + } +} + +void URLRequestCustomJobProxy::redirect(GURL url) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + if (!m_job) + return; + if (m_job->m_device || m_job->m_error) + return; + m_job->m_redirect = url; + m_started = true; + m_job->NotifyHeadersComplete(); +} + +void URLRequestCustomJobProxy::abort() +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + if (!m_job) + return; + if (m_job->m_device && m_job->m_device->isOpen()) + m_job->m_device->close(); + m_job->m_device = nullptr; + if (m_started) + m_job->NotifyCanceled(); + else + m_job->NotifyStartError(URLRequestStatus(URLRequestStatus::CANCELED, ERR_ABORTED)); +} + +void URLRequestCustomJobProxy::fail(int error) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + if (!m_job) + return; + m_job->m_error = error; + if (m_job->m_device) + m_job->m_device->close(); + if (!m_started) + m_job->NotifyStartError(URLRequestStatus::FromError(error)); + // else we fail on the next read, or the read that might already be in progress +} + +void URLRequestCustomJobProxy::initialize(GURL url, std::string method) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + Q_ASSERT(!m_delegate); + + QWebEngineUrlSchemeHandler *schemeHandler = 0; + QSharedPointer<const BrowserContextAdapter> browserContext = m_adapter.toStrongRef(); + if (browserContext) + schemeHandler = browserContext->customUrlSchemeHandlers()[toQByteArray(m_scheme)]; + if (schemeHandler) { + m_delegate = new URLRequestCustomJobDelegate(this, toQt(url), + QByteArray::fromStdString(method)); + QWebEngineUrlRequestJob *requestJob = new QWebEngineUrlRequestJob(m_delegate); + schemeHandler->requestStarted(requestJob); + } +} + +} // namespace diff --git a/src/core/url_request_custom_job_proxy.h b/src/core/url_request_custom_job_proxy.h new file mode 100644 index 000000000..df7171f5e --- /dev/null +++ b/src/core/url_request_custom_job_proxy.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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 URL_REQUEST_CUSTOM_JOB_PROXY_H_ +#define URL_REQUEST_CUSTOM_JOB_PROXY_H_ + +#include "base/memory/weak_ptr.h" +#include "url/gurl.h" +#include <QtCore/QWeakPointer> + +QT_FORWARD_DECLARE_CLASS(QIODevice) + +namespace QtWebEngineCore { + +class URLRequestCustomJob; +class URLRequestCustomJobDelegate; +class BrowserContextAdapter; + +// Used to comunicate between URLRequestCustomJob living on the IO thread +// and URLRequestCustomJobDelegate living on the UI thread. +class URLRequestCustomJobProxy + : public base::RefCountedThreadSafe<URLRequestCustomJobProxy> { + +public: + URLRequestCustomJobProxy(URLRequestCustomJob *job, + const std::string &scheme, + QWeakPointer<const BrowserContextAdapter> adapter); + ~URLRequestCustomJobProxy(); + + //void setReplyCharset(const std::string &); + void reply(std::string mimeType, QIODevice *device); + void redirect(GURL url); + void abort(); + void fail(int error); + void release(); + void initialize(GURL url, std::string method); + + //IO thread owned + URLRequestCustomJob *m_job; + bool m_started; + + //UI thread owned + std::string m_scheme; + URLRequestCustomJobDelegate *m_delegate; + QWeakPointer<const BrowserContextAdapter> m_adapter; +}; + +} // namespace QtWebEngineCore + +#endif // URL_REQUEST_CUSTOM_JOB_PROXY_H_ diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 7c74bb7fd..1f0c996ef 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -50,7 +50,6 @@ #include "browser_context_qt.h" #include "download_manager_delegate_qt.h" #include "media_capture_devices_dispatcher.h" -#include "pdfium_document_wrapper_qt.h" #include "print_view_manager_qt.h" #include "qwebenginecallback_p.h" #include "renderer_host/web_channel_ipc_transport_host.h" @@ -83,6 +82,8 @@ #include "content/public/common/web_preferences.h" #include "third_party/WebKit/public/web/WebFindOptions.h" #include "printing/features/features.h" +#include "ui/base/clipboard/clipboard.h" +#include "ui/base/clipboard/custom_data_helper.h" #include "ui/gfx/font_render_params.h" #include <QDir> @@ -109,37 +110,37 @@ static QVariant fromJSValue(const base::Value *result) { QVariant ret; switch (result->GetType()) { - case base::Value::TYPE_NULL: + case base::Value::Type::NONE: break; - case base::Value::TYPE_BOOLEAN: + case base::Value::Type::BOOLEAN: { bool out; if (result->GetAsBoolean(&out)) ret.setValue(out); break; } - case base::Value::TYPE_INTEGER: + case base::Value::Type::INTEGER: { int out; if (result->GetAsInteger(&out)) ret.setValue(out); break; } - case base::Value::TYPE_DOUBLE: + case base::Value::Type::DOUBLE: { double out; if (result->GetAsDouble(&out)) ret.setValue(out); break; } - case base::Value::TYPE_STRING: + case base::Value::Type::STRING: { base::string16 out; if (result->GetAsString(&out)) ret.setValue(toQt(out)); break; } - case base::Value::TYPE_LIST: + case base::Value::Type::LIST: { const base::ListValue *out; if (result->GetAsList(&out)) { @@ -154,7 +155,7 @@ static QVariant fromJSValue(const base::Value *result) } break; } - case base::Value::TYPE_DICTIONARY: + case base::Value::Type::DICTIONARY: { const base::DictionaryValue *out; if (result->GetAsDictionary(&out)) { @@ -168,10 +169,9 @@ static QVariant fromJSValue(const base::Value *result) } break; } - case base::Value::TYPE_BINARY: + case base::Value::Type::BINARY: { - const base::BinaryValue *out = static_cast<const base::BinaryValue*>(result); - QByteArray data(out->GetBuffer(), out->GetSize()); + QByteArray data(result->GetBlob().data(), result->GetBlob().size()); ret.setValue(data); break; } @@ -350,7 +350,7 @@ WebContentsAdapterPrivate::WebContentsAdapterPrivate() , adapterClient(0) , nextRequestId(CallbackDirectory::ReservedCallbackIdsEnd) , lastFindRequestId(0) - , currentDropAction(blink::WebDragOperationNone) + , currentDropAction(blink::kWebDragOperationNone) { } @@ -501,14 +501,14 @@ void WebContentsAdapter::stop() void WebContentsAdapter::reload() { Q_D(WebContentsAdapter); - d->webContents->GetController().Reload(/*checkRepost = */false); + d->webContents->GetController().Reload(content::ReloadType::NORMAL, /*checkRepost = */false); focusIfNecessary(); } void WebContentsAdapter::reloadAndBypassCache() { Q_D(WebContentsAdapter); - d->webContents->GetController().ReloadBypassingCache(/*checkRepost = */false); + d->webContents->GetController().Reload(content::ReloadType::BYPASSING_CACHE, /*checkRepost = */false); focusIfNecessary(); } @@ -610,7 +610,7 @@ void WebContentsAdapter::setContent(const QByteArray &data, const QString &mimeT params.override_user_agent = content::NavigationController::UA_OVERRIDE_TRUE; d->webContents->GetController().LoadURLWithParams(params); focusIfNecessary(); - d->webContents->Unselect(); + d->webContents->CollapseSelection(); } void WebContentsAdapter::save(const QString &filePath, int savePageFormat) @@ -718,7 +718,7 @@ void WebContentsAdapter::requestClose() void WebContentsAdapter::unselect() { Q_D(const WebContentsAdapter); - d->webContents->Unselect(); + d->webContents->CollapseSelection(); } void WebContentsAdapter::navigateToIndex(int offset) @@ -900,8 +900,8 @@ quint64 WebContentsAdapter::findText(const QString &subString, bool caseSensitiv blink::WebFindOptions options; options.forward = !findBackward; - options.matchCase = caseSensitively; - options.findNext = subString == d->webContentsDelegate->lastSearchedString(); + options.match_case = caseSensitively; + options.find_next = subString == d->webContentsDelegate->lastSearchedString(); d->webContentsDelegate->setLastSearchedString(subString); // Find already allows a request ID as input, but only as an int. @@ -916,9 +916,6 @@ void WebContentsAdapter::stopFinding() { Q_D(WebContentsAdapter); d->webContentsDelegate->setLastSearchedString(QString()); - // Clear any previous selection, - // but keep the renderer blue rectangle selection just like Chromium does. - d->webContents->Unselect(); d->webContents->StopFinding(content::STOP_FIND_ACTION_KEEP_SELECTION); } @@ -983,11 +980,11 @@ void WebContentsAdapter::copyImageAt(const QPoint &location) d->webContents->GetRenderViewHost()->GetMainFrame()->CopyImageAt(location.x(), location.y()); } -ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerNoAction, blink::WebMediaPlayerAction::Unknown) -ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerPlay, blink::WebMediaPlayerAction::Play) -ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerMute, blink::WebMediaPlayerAction::Mute) -ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerLoop, blink::WebMediaPlayerAction::Loop) -ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerControls, blink::WebMediaPlayerAction::Controls) +ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerNoAction, blink::WebMediaPlayerAction::kUnknown) +ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerPlay, blink::WebMediaPlayerAction::kPlay) +ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerMute, blink::WebMediaPlayerAction::kMute) +ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerLoop, blink::WebMediaPlayerAction::kLoop) +ASSERT_ENUMS_MATCH(WebContentsAdapter::MediaPlayerControls, blink::WebMediaPlayerAction::kControls) void WebContentsAdapter::executeMediaPlayerActionAt(const QPoint &location, MediaPlayerAction action, bool enable) { @@ -1178,18 +1175,23 @@ static QMimeData *mimeDataFromDropData(const content::DropData &dropData) mimeData->setHtml(toQt(dropData.html.string())); if (dropData.url.is_valid()) mimeData->setUrls(QList<QUrl>() << toQt(dropData.url)); + if (!dropData.custom_data.empty()) { + base::Pickle pickle; + ui::WriteCustomDataToPickle(dropData.custom_data, &pickle); + mimeData->setData(toQt(ui::Clipboard::GetWebCustomDataFormatType().ToString()), QByteArray((const char*)pickle.data(), pickle.size())); + } return mimeData; } static blink::WebDragOperationsMask toWeb(const Qt::DropActions action) { - int result = blink::WebDragOperationNone; + int result = blink::kWebDragOperationNone; if (action & Qt::CopyAction) - result |= blink::WebDragOperationCopy; + result |= blink::kWebDragOperationCopy; if (action & Qt::LinkAction) - result |= blink::WebDragOperationLink; + result |= blink::kWebDragOperationLink; if (action & Qt::MoveAction) - result |= blink::WebDragOperationMove; + result |= blink::kWebDragOperationMove; return static_cast<blink::WebDragOperationsMask>(result); } @@ -1207,16 +1209,14 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD d->currentDropData.reset(new content::DropData(dropData)); d->currentDropData->download_metadata.clear(); d->currentDropData->file_contents.clear(); - d->currentDropData->file_description_filename.clear(); + d->currentDropData->file_contents_content_disposition.clear(); - d->currentDropAction = blink::WebDragOperationNone; + d->currentDropAction = blink::kWebDragOperationNone; QDrag *drag = new QDrag(dragSource); // will be deleted by Qt's DnD implementation bool dValid = true; QMetaObject::Connection onDestroyed = QObject::connect(dragSource, &QObject::destroyed, [&dValid](){ dValid = false; -#if (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)) QDrag::cancel(); -#endif }); QMimeData *mimeData = mimeDataFromDropData(*d->currentDropData); @@ -1264,7 +1264,8 @@ bool WebContentsAdapter::handleDropDataFileContents(const content::DropData &dro } } - const QString &fileName = toQt(dropData.file_description_filename); + const auto maybeFilename = dropData.GetSafeFilenameForImageFileContents(); + const QString fileName = maybeFilename ? toQt(maybeFilename->AsUTF16Unsafe()) : QString(); const QString &filePath = d->dndTmpDir->filePath(fileName); QFile file(filePath); if (!file.open(QIODevice::WriteOnly)) { @@ -1294,6 +1295,10 @@ static void fillDropDataFromMimeData(content::DropData *dropData, const QMimeDat dropData->html = toNullableString16(mimeData->html()); if (mimeData->hasText()) dropData->text = toNullableString16(mimeData->text()); + if (mimeData->hasFormat(toQt(ui::Clipboard::GetWebCustomDataFormatType().ToString()))) { + QByteArray customData = mimeData->data(toQt(ui::Clipboard::GetWebCustomDataFormatType().ToString())); + ui::ReadCustomDataIntoMap(customData.constData(), customData.length(), &dropData->custom_data); + } } void WebContentsAdapter::enterDrag(QDragEnterEvent *e, const QPoint &screenPos) @@ -1315,11 +1320,11 @@ void WebContentsAdapter::enterDrag(QDragEnterEvent *e, const QPoint &screenPos) Qt::DropAction toQt(blink::WebDragOperation op) { - if (op & blink::WebDragOperationCopy) + if (op & blink::kWebDragOperationCopy) return Qt::CopyAction; - if (op & blink::WebDragOperationLink) + if (op & blink::kWebDragOperationLink) return Qt::LinkAction; - if (op & blink::WebDragOperationMove || op & blink::WebDragOperationDelete) + if (op & blink::kWebDragOperationMove || op & blink::kWebDragOperationDelete) return Qt::MoveAction; return Qt::IgnoreAction; } @@ -1328,11 +1333,11 @@ static int toWeb(Qt::MouseButtons buttons) { int result = 0; if (buttons & Qt::LeftButton) - result |= blink::WebInputEvent::LeftButtonDown; + result |= blink::WebInputEvent::kLeftButtonDown; if (buttons & Qt::RightButton) - result |= blink::WebInputEvent::RightButtonDown; + result |= blink::WebInputEvent::kRightButtonDown; if (buttons & Qt::MiddleButton) - result |= blink::WebInputEvent::MiddleButtonDown; + result |= blink::WebInputEvent::kMiddleButtonDown; return result; } @@ -1340,13 +1345,13 @@ static int toWeb(Qt::KeyboardModifiers modifiers) { int result = 0; if (modifiers & Qt::ShiftModifier) - result |= blink::WebInputEvent::ShiftKey; + result |= blink::WebInputEvent::kShiftKey; if (modifiers & Qt::ControlModifier) - result |= blink::WebInputEvent::ControlKey; + result |= blink::WebInputEvent::kControlKey; if (modifiers & Qt::AltModifier) - result |= blink::WebInputEvent::AltKey; + result |= blink::WebInputEvent::kAltKey; if (modifiers & Qt::MetaModifier) - result |= blink::WebInputEvent::MetaKey; + result |= blink::WebInputEvent::kMetaKey; return result; } @@ -1406,7 +1411,7 @@ void WebContentsAdapter::leaveDrag() { Q_D(WebContentsAdapter); content::RenderViewHost *rvh = d->webContents->GetRenderViewHost(); - rvh->GetWidget()->DragTargetDragLeave(); + rvh->GetWidget()->DragTargetDragLeave(d->lastDragClientPos, d->lastDragScreenPos); d->currentDropData.reset(); } @@ -1488,13 +1493,13 @@ ASSERT_ENUMS_MATCH(WebContentsAdapterClient::SaveToDiskDisposition, WindowOpenDi ASSERT_ENUMS_MATCH(WebContentsAdapterClient::OffTheRecordDisposition, WindowOpenDisposition::OFF_THE_RECORD) ASSERT_ENUMS_MATCH(WebContentsAdapterClient::IgnoreActionDisposition, WindowOpenDisposition::IGNORE_ACTION) -ASSERT_ENUMS_MATCH(ReferrerPolicy::Always, blink::WebReferrerPolicyAlways) -ASSERT_ENUMS_MATCH(ReferrerPolicy::Default, blink::WebReferrerPolicyDefault) -ASSERT_ENUMS_MATCH(ReferrerPolicy::NoReferrerWhenDowngrade, blink::WebReferrerPolicyNoReferrerWhenDowngrade) -ASSERT_ENUMS_MATCH(ReferrerPolicy::Never, blink::WebReferrerPolicyNever) -ASSERT_ENUMS_MATCH(ReferrerPolicy::Origin, blink::WebReferrerPolicyOrigin) -ASSERT_ENUMS_MATCH(ReferrerPolicy::OriginWhenCrossOrigin, blink::WebReferrerPolicyOriginWhenCrossOrigin) -ASSERT_ENUMS_MATCH(ReferrerPolicy::NoReferrerWhenDowngradeOriginWhenCrossOrigin, blink::WebReferrerPolicyNoReferrerWhenDowngradeOriginWhenCrossOrigin) -ASSERT_ENUMS_MATCH(ReferrerPolicy::Last, blink::WebReferrerPolicyLast) +ASSERT_ENUMS_MATCH(ReferrerPolicy::Always, blink::kWebReferrerPolicyAlways) +ASSERT_ENUMS_MATCH(ReferrerPolicy::Default, blink::kWebReferrerPolicyDefault) +ASSERT_ENUMS_MATCH(ReferrerPolicy::NoReferrerWhenDowngrade, blink::kWebReferrerPolicyNoReferrerWhenDowngrade) +ASSERT_ENUMS_MATCH(ReferrerPolicy::Never, blink::kWebReferrerPolicyNever) +ASSERT_ENUMS_MATCH(ReferrerPolicy::Origin, blink::kWebReferrerPolicyOrigin) +ASSERT_ENUMS_MATCH(ReferrerPolicy::OriginWhenCrossOrigin, blink::kWebReferrerPolicyOriginWhenCrossOrigin) +ASSERT_ENUMS_MATCH(ReferrerPolicy::NoReferrerWhenDowngradeOriginWhenCrossOrigin, blink::kWebReferrerPolicyNoReferrerWhenDowngradeOriginWhenCrossOrigin) +ASSERT_ENUMS_MATCH(ReferrerPolicy::Last, blink::kWebReferrerPolicyLast) } // namespace QtWebEngineCore diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index 3cc5350df..4280dbfe1 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -101,6 +101,7 @@ public: uint mediaFlags; QPoint pos; QUrl linkUrl; + QUrl unfilteredLinkUrl; QUrl mediaUrl; QString linkText; QString selectedText; @@ -170,6 +171,14 @@ public: return d->linkUrl; } + void setUnfilteredLinkUrl(const QUrl &url) { + d->unfilteredLinkUrl = url; + } + + QUrl unfilteredLinkUrl() const { + return d->unfilteredLinkUrl; + } + void setLinkText(const QString &text) { d->linkText = text; } @@ -307,7 +316,7 @@ public: IgnoreActionDisposition = 9, }; - // Must match the values in javascript_message_type.h. + // Must match the values in javascript_dialog_type.h. enum JavascriptDialogType { AlertDialog, ConfirmDialog, @@ -349,6 +358,8 @@ public: MediaNone = 0, MediaAudioCapture = 0x01, MediaVideoCapture = 0x02, + MediaDesktopAudioCapture = 0x04, + MediaDesktopVideoCapture = 0x08 }; Q_DECLARE_FLAGS(MediaRequestFlags, MediaRequestFlag) diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index 7d4c671b0..4bf25ff3b 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -63,6 +63,7 @@ #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/public/browser/invalidate_type.h" #include "content/public/browser/navigation_entry.h" +#include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" @@ -72,7 +73,6 @@ #include "content/public/common/frame_navigate_params.h" #include "content/public/common/url_constants.h" #include "content/public/common/web_preferences.h" -#include "ui/events/latency_info.h" #include <QDesktopServices> #include <QTimer> @@ -93,6 +93,7 @@ WebContentsDelegateQt::WebContentsDelegateQt(content::WebContents *webContents, : m_viewClient(adapterClient) , m_lastReceivedFindReply(0) , m_faviconManager(new FaviconManager(new FaviconManagerPrivate(webContents, adapterClient))) + , m_lastLoadProgress(-1) { webContents->SetDelegate(this); Observe(webContents); @@ -169,14 +170,18 @@ void WebContentsDelegateQt::AddNewContents(content::WebContents* source, content void WebContentsDelegateQt::CloseContents(content::WebContents *source) { m_viewClient->close(); - GetJavaScriptDialogManager(source)->CancelDialogs(source, /* whatever?: */false, false); + GetJavaScriptDialogManager(source)->CancelDialogs(source, /* whatever?: */false); } -void WebContentsDelegateQt::LoadProgressChanged(content::WebContents* source, double progress) +void WebContentsDelegateQt::LoadProgressChanged(content::WebContents */*source*/, double progress) { if (!m_loadingErrorFrameList.isEmpty()) return; - m_viewClient->loadProgressChanged(qRound(progress * 100)); + if (m_lastLoadProgress < 0) // suppress signals that aren't between loadStarted and loadFinished + return; + m_lastLoadProgress = qMax(m_lastLoadProgress, qRound(progress * 100)); // ensure monotonicity + m_lastLoadProgress = qMin(m_lastLoadProgress, 100); + m_viewClient->loadProgressChanged(m_lastLoadProgress); } void WebContentsDelegateQt::HandleKeyboardEvent(content::WebContents *, const content::NativeWebKeyboardEvent &event) @@ -191,59 +196,110 @@ void WebContentsDelegateQt::RenderFrameDeleted(content::RenderFrameHost *render_ m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID()); } -void WebContentsDelegateQt::DidStartProvisionalLoadForFrame(content::RenderFrameHost* render_frame_host, const GURL& validated_url, bool is_error_page, bool is_iframe_srcdoc) +void WebContentsDelegateQt::EmitLoadStarted(const QUrl &url, bool isErrorPage) { - if (is_error_page) { - m_loadingErrorFrameList.append(render_frame_host->GetRoutingID()); - - // Trigger LoadStarted signal for main frame's error page only. - if (!render_frame_host->GetParent()) { - m_faviconManager->resetCandidates(); - m_viewClient->loadStarted(toQt(validated_url), true); - } + if (m_lastLoadProgress >= 0) // already running + return; + m_viewClient->loadStarted(url, isErrorPage); + m_viewClient->loadProgressChanged(0); + m_lastLoadProgress = 0; +} +void WebContentsDelegateQt::DidStartNavigation(content::NavigationHandle *navigation_handle) +{ + if (!navigation_handle->IsInMainFrame()) return; + + // Suppress extra loadStarted signal for data URL with specified base URL. + if (navigation_handle->GetURL().SchemeIs(url::kDataScheme)) { + content::NavigationEntry *pending_entry = navigation_handle->GetWebContents()->GetController().GetPendingEntry(); + + if (pending_entry && !pending_entry->GetBaseURLForDataURL().is_empty() && + navigation_handle->GetURL() == pending_entry->GetURL()) { + return; + } } - if (render_frame_host->GetParent()) - return; + // Error-pages are not reported as separate started navigations. + Q_ASSERT(!navigation_handle->IsErrorPage()); m_loadingErrorFrameList.clear(); m_faviconManager->resetCandidates(); - m_viewClient->loadStarted(toQt(validated_url)); + EmitLoadStarted(toQt(navigation_handle->GetURL())); } -void WebContentsDelegateQt::DidCommitProvisionalLoadForFrame(content::RenderFrameHost* render_frame_host, const GURL& url, ui::PageTransition transition_type) +void WebContentsDelegateQt::EmitLoadFinished(bool success, const QUrl &url, bool isErrorPage, int errorCode, const QString &errorDescription) { - // Make sure that we don't set the findNext WebFindOptions on a new frame. - m_lastSearchedString = QString(); + if (m_lastLoadProgress < 0) // not currently running + return; + m_lastLoadProgress = -1; + m_viewClient->loadProgressChanged(100); + m_viewClient->loadFinished(success, url, isErrorPage, errorCode, errorDescription); +} + +void WebContentsDelegateQt::DidFinishNavigation(content::NavigationHandle *navigation_handle) +{ + if (!navigation_handle->IsInMainFrame()) + return; + + if (navigation_handle->HasCommitted() && !navigation_handle->IsErrorPage()) { + // VisistedLinksMaster asserts !IsOffTheRecord(). + if (navigation_handle->ShouldUpdateHistory() && m_viewClient->browserContextAdapter()->trackVisitedLinks()) + m_viewClient->browserContextAdapter()->visitedLinksManager()->addUrl(navigation_handle->GetURL()); - // This is currently used for canGoBack/Forward values, which is flattened across frames. For other purposes we might have to pass is_main_frame. - m_viewClient->loadCommitted(); + // Make sure that we don't set the findNext WebFindOptions on a new frame. + m_lastSearchedString = QString(); + + // This is currently used for canGoBack/Forward values, which is flattened across frames. For other purposes we might have to pass is_main_frame. + m_viewClient->loadCommitted(); + } + // Success is reported by DidFinishLoad, but DidFailLoad is now dead code and needs to be handled below + if (navigation_handle->GetNetErrorCode() == net::OK) + return; + + // WebContentsObserver::DidFailLoad is not called any longer so we have to report the failure here. + const net::Error error_code = navigation_handle->GetNetErrorCode(); + const std::string error_description = net::ErrorToString(error_code); + didFailLoad(toQt(navigation_handle->GetURL()), error_code, toQt(error_description)); + + // The load will succede as an error-page load later, and we reported the original error above + if (navigation_handle->IsErrorPage()) { + // Now report we are starting to load an error-page. + m_loadingErrorFrameList.append(navigation_handle->GetRenderFrameHost()->GetRoutingID()); + m_faviconManager->resetCandidates(); + EmitLoadStarted(toQt(GURL(content::kUnreachableWebDataURL)), true); + + // If it is already committed we will not see another DidFinishNavigation call or a DidFinishLoad call. + if (navigation_handle->HasCommitted()) { + m_lastSearchedString = QString(); + m_viewClient->loadCommitted(); + } + } } -void WebContentsDelegateQt::DidFailProvisionalLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code, const base::string16& error_description, bool was_ignored_by_handler) +void WebContentsDelegateQt::didFailLoad(const QUrl &url, int errorCode, const QString &errorDescription) { - DidFailLoad(render_frame_host, validated_url, error_code, error_description, was_ignored_by_handler); + m_viewClient->iconChanged(QUrl()); + EmitLoadFinished(false /* success */ , url, false /* isErrorPage */, errorCode, errorDescription); } void WebContentsDelegateQt::DidFailLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code, const base::string16& error_description, bool was_ignored_by_handler) { Q_UNUSED(was_ignored_by_handler); + if (render_frame_host->GetParent()) + return; + if (validated_url.spec() == content::kUnreachableWebDataURL) { + // error-pages should only ever fail due to abort: + Q_ASSERT(error_code == -3 /* ERR_ABORTED */); m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID()); - qCritical("Loading error-page failed. This shouldn't happen."); - if (!render_frame_host->GetParent()) - m_viewClient->loadFinished(false /* success */, toQt(validated_url), true /* isErrorPage */); - return; - } + m_viewClient->iconChanged(QUrl()); - if (render_frame_host->GetParent()) + EmitLoadFinished(false /* success */, toQt(validated_url), true /* isErrorPage */); return; + } - m_viewClient->iconChanged(QUrl()); - m_viewClient->loadFinished(false /* success */ , toQt(validated_url), false /* isErrorPage */, error_code, toQt(error_description)); - m_viewClient->loadProgressChanged(0); + didFailLoad(toQt(validated_url), error_code, toQt(error_description)); } void WebContentsDelegateQt::DidFinishLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url) @@ -255,7 +311,7 @@ void WebContentsDelegateQt::DidFinishLoad(content::RenderFrameHost* render_frame // Trigger LoadFinished signal for main frame's error page only. if (!render_frame_host->GetParent()) - m_viewClient->loadFinished(true /* success */, toQt(validated_url), true /* isErrorPage */); + EmitLoadFinished(true /* success */, toQt(validated_url), true /* isErrorPage */); return; } @@ -266,8 +322,7 @@ void WebContentsDelegateQt::DidFinishLoad(content::RenderFrameHost* render_frame if (!m_faviconManager->hasCandidate()) m_viewClient->iconChanged(QUrl()); - m_viewClient->loadProgressChanged(100); - m_viewClient->loadFinished(true, toQt(validated_url)); + EmitLoadFinished(true, toQt(validated_url)); } void WebContentsDelegateQt::DidUpdateFaviconURL(const std::vector<content::FaviconURL> &candidates) @@ -282,7 +337,7 @@ void WebContentsDelegateQt::DidUpdateFaviconURL(const std::vector<content::Favic m_faviconManager->update(faviconCandidates); } -void WebContentsDelegateQt::WebContentsCreated(content::WebContents* /*source_contents*/, int /*opener_render_process_id*/, int /*opener_render_frame_id*/, const std::string& /*frame_name*/, const GURL& target_url, content::WebContents* new_contents) +void WebContentsDelegateQt::WebContentsCreated(content::WebContents* /*source_contents*/, int /*opener_render_process_id*/, int /*opener_render_frame_id*/, const std::string& /*frame_name*/, const GURL& target_url, content::WebContents* new_contents, const base::Optional<content::WebContents::CreateParams>& create_params) { this->m_initialTargetUrl = toQt(target_url); } @@ -380,14 +435,6 @@ void WebContentsDelegateQt::UpdateTargetURL(content::WebContents* source, const m_viewClient->didUpdateTargetURL(toQt(url)); } -void WebContentsDelegateQt::DidNavigateAnyFrame(content::RenderFrameHost* render_frame_host, const content::LoadCommittedDetails& details, const content::FrameNavigateParams& params) -{ - // VisistedLinksMaster asserts !IsOffTheRecord(). - if (!params.should_update_history || !m_viewClient->browserContextAdapter()->trackVisitedLinks()) - return; - m_viewClient->browserContextAdapter()->visitedLinksManager()->addUrl(params.url); -} - void WebContentsDelegateQt::WasShown() { web_cache::WebCacheManager::GetInstance()->ObserveActivity(web_contents()->GetRenderProcessHost()->GetID()); @@ -408,6 +455,13 @@ void WebContentsDelegateQt::DidFirstVisuallyNonEmptyPaint() } } +void WebContentsDelegateQt::ActivateContents(content::WebContents* contents) +{ + WebEngineSettings *settings = m_viewClient->webEngineSettings(); + if (settings->testAttribute(settings->Attribute::AllowWindowActivationFromJavaScript)) + contents->Focus(); +} + void WebContentsDelegateQt::RequestToLockMouse(content::WebContents *web_contents, bool user_gesture, bool last_unlocked_by_target) { Q_UNUSED(user_gesture); @@ -482,6 +536,10 @@ void WebContentsDelegateQt::BeforeUnloadFired(content::WebContents *tab, bool pr m_viewClient->windowCloseRejected(); } +void WebContentsDelegateQt::BeforeUnloadFired(const base::TimeTicks &proceed_time) { + Q_UNUSED(proceed_time); +} + bool WebContentsDelegateQt::CheckMediaAccessPermission(content::WebContents *web_contents, const GURL& security_origin, content::MediaStreamType type) { switch (type) { @@ -501,4 +559,8 @@ FaviconManager *WebContentsDelegateQt::faviconManager() return m_faviconManager.data(); } +WebEngineSettings *WebContentsDelegateQt::webEngineSettings() const { + return m_viewClient->webEngineSettings(); +} + } // namespace QtWebEngineCore diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h index 913bf356c..2e37c498a 100644 --- a/src/core/web_contents_delegate_qt.h +++ b/src/core/web_contents_delegate_qt.h @@ -68,6 +68,7 @@ namespace content { namespace QtWebEngineCore { class WebContentsAdapterClient; +class WebEngineSettings; class SavePageInfo { @@ -104,7 +105,7 @@ public: void LoadProgressChanged(content::WebContents* source, double progress) override; void HandleKeyboardEvent(content::WebContents *source, const content::NativeWebKeyboardEvent &event) override; content::ColorChooser *OpenColorChooser(content::WebContents *source, SkColor color, const std::vector<content::ColorSuggestion> &suggestion) override; - void WebContentsCreated(content::WebContents* source_contents, int opener_render_process_id, int opener_render_frame_id, const std::string& frame_name, const GURL& target_url, content::WebContents* new_contents) override; + void WebContentsCreated(content::WebContents* source_contents, int opener_render_process_id, int opener_render_frame_id, const std::string& frame_name, const GURL& target_url, content::WebContents* new_contents, const base::Optional<content::WebContents::CreateParams>& create_params) override; content::JavaScriptDialogManager *GetJavaScriptDialogManager(content::WebContents *source) override; void EnterFullscreenModeForTab(content::WebContents* web_contents, const GURL& origin) override; void ExitFullscreenModeForTab(content::WebContents*) override; @@ -126,18 +127,18 @@ public: // WebContentsObserver overrides void RenderFrameDeleted(content::RenderFrameHost *render_frame_host) override; - void DidStartProvisionalLoadForFrame(content::RenderFrameHost *render_frame_host, const GURL &validated_url, bool is_error_page, bool is_iframe_srcdoc) override; - void DidCommitProvisionalLoadForFrame(content::RenderFrameHost *render_frame_host, const GURL &url, ui::PageTransition transition_type) override; - void DidFailProvisionalLoad(content::RenderFrameHost *render_frame_host, const GURL &validated_url, - int error_code, const base::string16 &error_description, bool was_ignored_by_handler) override; + void DidStartNavigation(content::NavigationHandle *navigation_handle) override; + void DidFinishNavigation(content::NavigationHandle *navigation_handle) override; void DidFailLoad(content::RenderFrameHost *render_frame_host, const GURL &validated_url, int error_code, const base::string16 &error_description, bool was_ignored_by_handler) override; void DidFinishLoad(content::RenderFrameHost *render_frame_host, const GURL &validated_url) override; + void BeforeUnloadFired(const base::TimeTicks& proceed_time) override; void DidUpdateFaviconURL(const std::vector<content::FaviconURL> &candidates) override; - void DidNavigateAnyFrame(content::RenderFrameHost *render_frame_host, const content::LoadCommittedDetails &details, const content::FrameNavigateParams ¶ms) override; void WasShown() override; void DidFirstVisuallyNonEmptyPaint() override; + void ActivateContents(content::WebContents* contents) override; + void didFailLoad(const QUrl &url, int errorCode, const QString &errorDescription); void overrideWebPreferences(content::WebContents *, content::WebPreferences*); void allowCertificateError(const QSharedPointer<CertificateErrorController> &) ; void requestGeolocationPermission(const QUrl &requestingOrigin); @@ -147,8 +148,12 @@ public: void setSavePageInfo(const SavePageInfo &spi) { m_savePageInfo = spi; } const SavePageInfo &savePageInfo() { return m_savePageInfo; } + WebEngineSettings *webEngineSettings() const; + private: QWeakPointer<WebContentsAdapter> createWindow(content::WebContents *new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture); + void EmitLoadStarted(const QUrl &url, bool isErrorPage = false); + void EmitLoadFinished(bool success, const QUrl &url, bool isErrorPage = false, int errorCode = 0, const QString &errorDescription = QString()); WebContentsAdapterClient *m_viewClient; QString m_lastSearchedString; @@ -158,6 +163,7 @@ private: SavePageInfo m_savePageInfo; QSharedPointer<FilePickerController> m_filePickerController; QUrl m_initialTargetUrl; + int m_lastLoadProgress; }; } // namespace QtWebEngineCore diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp index 86e839a7f..28f202e24 100644 --- a/src/core/web_contents_view_qt.cpp +++ b/src/core/web_contents_view_qt.cpp @@ -138,25 +138,25 @@ void WebContentsViewQt::SetInitialFocus() Focus(); } -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeNone, blink::WebContextMenuData::MediaTypeNone) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeImage, blink::WebContextMenuData::MediaTypeImage) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeVideo, blink::WebContextMenuData::MediaTypeVideo) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeAudio, blink::WebContextMenuData::MediaTypeAudio) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeCanvas, blink::WebContextMenuData::MediaTypeCanvas) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeFile, blink::WebContextMenuData::MediaTypeFile) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypePlugin, blink::WebContextMenuData::MediaTypePlugin) - -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaNone, blink::WebContextMenuData::MediaNone) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaInError, blink::WebContextMenuData::MediaInError) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaPaused, blink::WebContextMenuData::MediaPaused) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaMuted, blink::WebContextMenuData::MediaMuted) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaLoop, blink::WebContextMenuData::MediaLoop) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanSave, blink::WebContextMenuData::MediaCanSave) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaHasAudio, blink::WebContextMenuData::MediaHasAudio) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanToggleControls, blink::WebContextMenuData::MediaCanToggleControls) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaControls, blink::WebContextMenuData::MediaControls) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanPrint, blink::WebContextMenuData::MediaCanPrint) -ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanRotate, blink::WebContextMenuData::MediaCanRotate) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeNone, blink::WebContextMenuData::kMediaTypeNone) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeImage, blink::WebContextMenuData::kMediaTypeImage) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeVideo, blink::WebContextMenuData::kMediaTypeVideo) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeAudio, blink::WebContextMenuData::kMediaTypeAudio) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeCanvas, blink::WebContextMenuData::kMediaTypeCanvas) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypeFile, blink::WebContextMenuData::kMediaTypeFile) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaTypePlugin, blink::WebContextMenuData::kMediaTypePlugin) + +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaNone, blink::WebContextMenuData::kMediaNone) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaInError, blink::WebContextMenuData::kMediaInError) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaPaused, blink::WebContextMenuData::kMediaPaused) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaMuted, blink::WebContextMenuData::kMediaMuted) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaLoop, blink::WebContextMenuData::kMediaLoop) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanSave, blink::WebContextMenuData::kMediaCanSave) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaHasAudio, blink::WebContextMenuData::kMediaHasAudio) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanToggleControls, blink::WebContextMenuData::kMediaCanToggleControls) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaControls, blink::WebContextMenuData::kMediaControls) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanPrint, blink::WebContextMenuData::kMediaCanPrint) +ASSERT_ENUMS_MATCH(WebEngineContextMenuData::MediaCanRotate, blink::WebContextMenuData::kMediaCanRotate) static inline WebEngineContextMenuData fromParams(const content::ContextMenuParams ¶ms) { @@ -164,6 +164,7 @@ static inline WebEngineContextMenuData fromParams(const content::ContextMenuPara ret.setPosition(QPoint(params.x, params.y)); ret.setLinkUrl(toQt(params.link_url)); ret.setLinkText(toQt(params.link_text.data())); + ret.setUnfilteredLinkUrl(toQt(params.unfiltered_link_url)); ret.setSelectedText(toQt(params.selection_text.data())); ret.setMediaUrl(toQt(params.src_url)); ret.setMediaType((WebEngineContextMenuData::MediaType)params.media_type); @@ -200,11 +201,11 @@ void WebContentsViewQt::ShowContextMenu(content::RenderFrameHost *, const conten Qt::DropActions toQtDropActions(blink::WebDragOperationsMask ops) { Qt::DropActions result; - if (ops & blink::WebDragOperationCopy) + if (ops & blink::kWebDragOperationCopy) result |= Qt::CopyAction; - if (ops & blink::WebDragOperationLink) + if (ops & blink::kWebDragOperationLink) result |= Qt::LinkAction; - if (ops & blink::WebDragOperationMove || ops & blink::WebDragOperationDelete) + if (ops & blink::kWebDragOperationMove || ops & blink::kWebDragOperationDelete) result |= Qt::MoveAction; return result; } diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index 900b82eb9..2339537aa 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -52,7 +52,7 @@ #include "chrome/browser/printing/print_job_manager.h" #endif // defined(ENABLE_BASIC_PRINTING) #include "content/browser/devtools/devtools_http_handler.h" -#include "content/browser/gpu/gpu_process_host.h" +#include "content/browser/gpu/gpu_main_thread_factory.h" #include "content/browser/renderer_host/render_process_host_impl.h" #include "content/browser/utility_process_host_impl.h" #include "content/gpu/in_process_gpu_thread.h" @@ -61,6 +61,7 @@ #include "content/public/browser/browser_main_runner.h" #include "content/public/browser/plugin_service.h" #include "content/public/browser/render_frame_host.h" +#include "content/public/common/content_features.h" #include "content/public/common/content_paths.h" #include "content/public/common/content_switches.h" #include "content/public/common/main_function_params.h" @@ -68,8 +69,9 @@ #include "content/utility/in_process_utility_thread.h" #include "gpu/command_buffer/service/gpu_switches.h" #include "net/base/port_util.h" +#include "ppapi/features/features.h" #include "ui/events/event_switches.h" -#include "ui/native_theme/native_theme_switches.h" +#include "ui/native_theme/native_theme_features.h" #include "ui/gl/gl_switches.h" #if defined(OS_WIN) #include "sandbox/win/src/sandbox_types.h" @@ -159,7 +161,7 @@ bool usingQtQuick2DRenderer() return device != QLatin1String("default"); } #endif //QT_NO_OPENGL -#if defined(ENABLE_PLUGINS) +#if BUILDFLAG(ENABLE_PLUGINS) void dummyGetPluginCallback(const std::vector<content::WebPluginInfo>&) { } @@ -195,7 +197,8 @@ void WebEngineContext::destroy() m_devtoolsServer->stop(); delete m_globalQObject; m_globalQObject = 0; - base::MessagePump::Delegate *delegate = m_runLoop->loop_; + base::MessagePump::Delegate *delegate = + static_cast<base::MessageLoop *>(m_runLoop->delegate_); // Flush the UI message loop before quitting. while (delegate->DoWork()) { } GLContextHelper::destroy(); @@ -284,8 +287,10 @@ WebEngineContext::WebEngineContext() appArgs.append(QString::fromLocal8Bit(qgetenv(kChromiumFlagsEnv)).split(' ')); } +#ifdef Q_OS_WIN bool enableWebGLSoftwareRendering = appArgs.removeAll(QStringLiteral("--enable-webgl-software-rendering")); +#endif bool useEmbeddedSwitches = false; #if defined(QTWEBENGINE_EMBEDDED_SWITCHES) @@ -320,7 +325,6 @@ WebEngineContext::WebEngineContext() } parsedCommandLine->AppendSwitch(switches::kEnableThreadedCompositing); - parsedCommandLine->AppendSwitch(switches::kInProcessGPU); // These are currently only default on OS X, and we don't support them: parsedCommandLine->AppendSwitch(switches::kDisableZeroCopy); parsedCommandLine->AppendSwitch(switches::kDisableGpuMemoryBufferCompositorResources); @@ -347,10 +351,15 @@ WebEngineContext::WebEngineContext() parsedCommandLine->AppendSwitch(switches::kDisableES3GLContext); #endif + // Needed to allow navigations within pages that were set using setHtml(). One example is + // tst_QWebEnginePage::acceptNavigationRequest. + // This is deprecated behavior, and will be removed in a future Chromium version, as per + // upstream Chromium commit ba52f56207a4b9d70b34880fbff2352e71a06422. + parsedCommandLine->AppendSwitchASCII(switches::kEnableFeatures, + features::kAllowContentInitiatedDataUrlNavigations.name); + if (useEmbeddedSwitches) { - // Inspired by the Android port's default switches - if (!parsedCommandLine->HasSwitch(switches::kDisableOverlayScrollbar)) - parsedCommandLine->AppendSwitch(switches::kEnableOverlayScrollbar); + parsedCommandLine->AppendSwitchASCII(switches::kEnableFeatures, features::kOverlayScrollbar.name); if (!parsedCommandLine->HasSwitch(switches::kDisablePinch)) parsedCommandLine->AppendSwitch(switches::kEnablePinch); parsedCommandLine->AppendSwitch(switches::kEnableViewport); @@ -434,23 +443,33 @@ WebEngineContext::WebEngineContext() } } } + + if (qt_gl_global_share_context()->format().profile() == QSurfaceFormat::CompatibilityProfile) + parsedCommandLine->AppendSwitch(switches::kCreateDefaultGLContext); } else { qWarning("WebEngineContext used before QtWebEngine::initialize() or OpenGL context creation failed."); } } #endif - if (glType) + if (glType) { parsedCommandLine->AppendSwitchASCII(switches::kUseGL, glType); - else + parsedCommandLine->AppendSwitch(switches::kInProcessGPU); +#ifdef Q_OS_WIN + if (enableWebGLSoftwareRendering) + parsedCommandLine->AppendSwitch(switches::kDisableGpuRasterization); +#endif + } else { parsedCommandLine->AppendSwitch(switches::kDisableGpu); + } content::UtilityProcessHostImpl::RegisterUtilityMainThreadFactory(content::CreateInProcessUtilityThread); content::RenderProcessHostImpl::RegisterRendererMainThreadFactory(content::CreateInProcessRendererThread); - content::GpuProcessHost::RegisterGpuMainThreadFactory(content::CreateInProcessGpuThread); + content::RegisterGpuMainThreadFactory(content::CreateInProcessGpuThread); + + mojo::edk::Init(); content::ContentMainParams contentMainParams(m_mainDelegate.get()); - contentMainParams.setup_signal_handlers = false; #if defined(OS_WIN) sandbox::SandboxInterfaceInfo sandbox_info = {0}; content::InitializeSandboxInfo(&sandbox_info); @@ -477,7 +496,7 @@ WebEngineContext::WebEngineContext() net::SetExplicitlyAllowedPorts(allowedPorts); } -#if defined(ENABLE_PLUGINS) +#if BUILDFLAG(ENABLE_PLUGINS) // Creating pepper plugins from the page (which calls PluginService::GetPluginInfoArray) // might fail unless the page queried the list of available plugins at least once // (which ends up calling PluginService::GetPlugins). Since the plugins list can only diff --git a/src/core/web_engine_library_info.cpp b/src/core/web_engine_library_info.cpp index f46f8f425..35b139602 100644 --- a/src/core/web_engine_library_info.cpp +++ b/src/core/web_engine_library_info.cpp @@ -216,26 +216,32 @@ QString dictionariesPath() if (!initialized) { initialized = true; - // First try to find dictionaries near the application. + const QByteArray fromEnv = qgetenv("QTWEBENGINE_DICTIONARIES_PATH"); + if (!fromEnv.isEmpty()) { + // Only search in QTWEBENGINE_DICTIONARIES_PATH if set + candidatePaths << QString::fromLocal8Bit(fromEnv); + } else { + // First try to find dictionaries near the application. #ifdef OS_MACOSX - QString resourcesDictionariesPath = getMainApplicationResourcesPath() - % QDir::separator() % QLatin1String("qtwebengine_dictionaries"); - candidatePaths << resourcesDictionariesPath; + QString resourcesDictionariesPath = getMainApplicationResourcesPath() + % QDir::separator() % QLatin1String("qtwebengine_dictionaries"); + candidatePaths << resourcesDictionariesPath; #endif - QString applicationDictionariesPath = QCoreApplication::applicationDirPath() - % QDir::separator() % QLatin1String("qtwebengine_dictionaries"); - candidatePaths << applicationDictionariesPath; + QString applicationDictionariesPath = QCoreApplication::applicationDirPath() + % QDir::separator() % QLatin1String("qtwebengine_dictionaries"); + candidatePaths << applicationDictionariesPath; - // Then try to find dictionaries near the installed library. + // Then try to find dictionaries near the installed library. #if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD) - QString frameworkDictionariesPath = getResourcesPath(frameworkBundle()) - % QLatin1String("/qtwebengine_dictionaries"); - candidatePaths << frameworkDictionariesPath; + QString frameworkDictionariesPath = getResourcesPath(frameworkBundle()) + % QLatin1String("/qtwebengine_dictionaries"); + candidatePaths << frameworkDictionariesPath; #endif - QString libraryDictionariesPath = QLibraryInfo::location(QLibraryInfo::DataPath) - % QDir::separator() % QLatin1String("qtwebengine_dictionaries"); - candidatePaths << libraryDictionariesPath; + QString libraryDictionariesPath = QLibraryInfo::location(QLibraryInfo::DataPath) + % QDir::separator() % QLatin1String("qtwebengine_dictionaries"); + candidatePaths << libraryDictionariesPath; + } Q_FOREACH (const QString &candidate, candidatePaths) { if (QFileInfo::exists(candidate)) { diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp index 0079e02ba..498c4e799 100644 --- a/src/core/web_engine_settings.cpp +++ b/src/core/web_engine_settings.cpp @@ -83,21 +83,6 @@ private: WebEngineSettings *m_settings; }; -static inline bool isTouchScreenAvailable() { - static bool initialized = false; - static bool touchScreenAvailable = false; - if (!initialized) { - Q_FOREACH (const QTouchDevice *d, QTouchDevice::devices()) { - if (d->type() == QTouchDevice::TouchScreen) { - touchScreenAvailable = true; - break; - } - } - initialized = true; - } - return touchScreenAvailable; -} - static inline bool isTouchEventsAPIEnabled() { static bool initialized = false; static bool touchEventsAPIEnabled = false; @@ -107,21 +92,20 @@ static inline bool isTouchEventsAPIEnabled() { // By default the Touch Events API support (presence of 'ontouchstart' in 'window' object) // will be determined based on the availability of touch screen devices. const std::string touchEventsSwitchValue = - parsedCommandLine->HasSwitch(switches::kTouchEvents) ? - parsedCommandLine->GetSwitchValueASCII(switches::kTouchEvents) : - switches::kTouchEventsAuto; + parsedCommandLine->HasSwitch(switches::kTouchEventFeatureDetection) ? + parsedCommandLine->GetSwitchValueASCII(switches::kTouchEventFeatureDetection) : + switches::kTouchEventFeatureDetectionAuto; - if (touchEventsSwitchValue == switches::kTouchEventsEnabled) + if (touchEventsSwitchValue == switches::kTouchEventFeatureDetectionEnabled) touchEventsAPIEnabled = true; - else if (touchEventsSwitchValue == switches::kTouchEventsAuto) - touchEventsAPIEnabled = isTouchScreenAvailable(); + else if (touchEventsSwitchValue == switches::kTouchEventFeatureDetectionAuto) + touchEventsAPIEnabled = (ui::GetTouchScreensAvailability() == ui::TouchScreensAvailability::ENABLED); initialized = true; } return touchEventsAPIEnabled; } - WebEngineSettings::WebEngineSettings(WebEngineSettings *_parentSettings) : m_adapter(0) , m_batchTimer(new BatchTimer(this)) @@ -228,7 +212,7 @@ QString WebEngineSettings::defaultTextEncoding() const return m_defaultEncoding.isEmpty()? parentSettings->defaultTextEncoding() : m_defaultEncoding; } -void WebEngineSettings::initDefaults(bool offTheRecord) +void WebEngineSettings::initDefaults() { if (s_defaultAttributes.isEmpty()) { // Initialize the default settings. @@ -247,6 +231,7 @@ void WebEngineSettings::initDefaults(bool offTheRecord) s_defaultAttributes.insert(PluginsEnabled, false); s_defaultAttributes.insert(FullScreenSupportEnabled, false); s_defaultAttributes.insert(ScreenCaptureEnabled, false); + s_defaultAttributes.insert(ShowScrollBars, true); // The following defaults matches logic in render_view_host_impl.cc // But first we must ensure the WebContext has been initialized QtWebEngineCore::WebEngineContext::current(); @@ -263,13 +248,12 @@ void WebEngineSettings::initDefaults(bool offTheRecord) s_defaultAttributes.insert(Accelerated2dCanvasEnabled, accelerated2dCanvas); s_defaultAttributes.insert(AutoLoadIconsForPage, true); s_defaultAttributes.insert(TouchIconsEnabled, false); - s_defaultAttributes.insert(FocusOnNavigationEnabled, true); + s_defaultAttributes.insert(FocusOnNavigationEnabled, false); s_defaultAttributes.insert(PrintElementBackgrounds, true); s_defaultAttributes.insert(AllowRunningInsecureContent, allowRunningInsecureContent); s_defaultAttributes.insert(AllowGeolocationOnInsecureOrigins, false); + s_defaultAttributes.insert(AllowWindowActivationFromJavaScript, false); } - if (offTheRecord) - m_attributes.insert(LocalStorageEnabled, false); if (s_defaultFontFamilies.isEmpty()) { // Default fonts @@ -322,8 +306,7 @@ void WebEngineSettings::doApply() void WebEngineSettings::applySettingsToWebPreferences(content::WebPreferences *prefs) { // Override for now - prefs->touch_enabled = isTouchEventsAPIEnabled(); - prefs->device_supports_touch = isTouchScreenAvailable(); + prefs->touch_event_feature_detection_enabled = isTouchEventsAPIEnabled(); if (prefs->viewport_enabled) { // We should enable viewport and viewport-meta together, but since 5.7 we // no longer have a command-line flag for viewport-meta. @@ -333,7 +316,6 @@ void WebEngineSettings::applySettingsToWebPreferences(content::WebPreferences *p // Attributes mapping. prefs->loads_images_automatically = testAttribute(AutoLoadImages); prefs->javascript_enabled = testAttribute(JavascriptEnabled); - prefs->javascript_can_open_windows_automatically = testAttribute(JavascriptCanOpenWindows); prefs->javascript_can_access_clipboard = testAttribute(JavascriptCanAccessClipboard); prefs->tabs_to_links = testAttribute(LinksIncludedInFocusChain); prefs->local_storage_enabled = testAttribute(LocalStorageEnabled); @@ -352,6 +334,7 @@ void WebEngineSettings::applySettingsToWebPreferences(content::WebPreferences *p prefs->should_print_backgrounds = testAttribute(PrintElementBackgrounds); prefs->allow_running_insecure_content = testAttribute(AllowRunningInsecureContent); prefs->allow_geolocation_on_insecure_origins = testAttribute(AllowGeolocationOnInsecureOrigins); + prefs->hide_scrollbars = !testAttribute(ShowScrollBars); // Fonts settings. prefs->standard_font_family_map[content::kCommonScript] = toString16(fontFamily(StandardFont)); @@ -376,6 +359,11 @@ void WebEngineSettings::scheduleApplyRecursively() } } +bool WebEngineSettings::getJavaScriptCanOpenWindowsAutomatically() +{ + return testAttribute(JavascriptCanOpenWindows); +} + void WebEngineSettings::setParentSettings(WebEngineSettings *_parentSettings) { if (parentSettings) diff --git a/src/core/web_engine_settings.h b/src/core/web_engine_settings.h index 4b0ce7b39..18963344a 100644 --- a/src/core/web_engine_settings.h +++ b/src/core/web_engine_settings.h @@ -83,7 +83,9 @@ public: FocusOnNavigationEnabled, PrintElementBackgrounds, AllowRunningInsecureContent, - AllowGeolocationOnInsecureOrigins + AllowGeolocationOnInsecureOrigins, + AllowWindowActivationFromJavaScript, + ShowScrollBars }; // Must match the values from the public API in qwebenginesettings.h. @@ -127,11 +129,13 @@ public: void setDefaultTextEncoding(const QString &encoding); QString defaultTextEncoding() const; - void initDefaults(bool offTheRecord = false); + void initDefaults(); void scheduleApply(); void scheduleApplyRecursively(); + bool getJavaScriptCanOpenWindowsAutomatically(); + private: void doApply(); void applySettingsToWebPreferences(content::WebPreferences *); diff --git a/src/core/web_event_factory.cpp b/src/core/web_event_factory.cpp index f5264708d..18f8d393f 100644 --- a/src/core/web_event_factory.cpp +++ b/src/core/web_event_factory.cpp @@ -72,12 +72,12 @@ #include <QCoreApplication> #include <QElapsedTimer> +#include <QGuiApplication> #include <QKeyEvent> #include <QMouseEvent> +#include <QStyleHints> #include <QWheelEvent> -static const int wheelScrollLines = 3; // FIXME: Still not available in QStyleHints in 5.1 - using namespace blink; static int windowsKeyCodeForKeyEvent(unsigned int keycode, bool isKeypad) @@ -902,11 +902,11 @@ static ui::DomKey getDomKeyFromQKeyEvent(QKeyEvent *ev) // Audio Keys case Qt::Key_BassDown: - return ui::DomKey::AUDIO_BASS_DOWN; + return ui::DomKey::AUDIO_BASS_BOOST_DOWN; case Qt::Key_BassBoost: return ui::DomKey::AUDIO_BASS_BOOST_TOGGLE; case Qt::Key_BassUp: - return ui::DomKey::AUDIO_BASS_UP; + return ui::DomKey::AUDIO_BASS_BOOST_UP; case Qt::Key_TrebleDown: return ui::DomKey::AUDIO_TREBLE_DOWN; case Qt::Key_TrebleUp: @@ -1035,25 +1035,25 @@ static inline double currentTimeForEvent(const QInputEvent* event) static WebMouseEvent::Button mouseButtonForEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) - return WebMouseEvent::Button::Left; + return WebMouseEvent::Button::kLeft; else if (event->button() == Qt::RightButton) - return WebMouseEvent::Button::Right; + return WebMouseEvent::Button::kRight; else if (event->button() == Qt::MidButton) - return WebMouseEvent::Button::Middle; + return WebMouseEvent::Button::kMiddle; if (event->type() != QEvent::MouseMove) - return WebMouseEvent::Button::NoButton; + return WebMouseEvent::Button::kNoButton; // 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::Button::Left; + return WebMouseEvent::Button::kLeft; else if (event->buttons() & Qt::RightButton) - return WebMouseEvent::Button::Right; + return WebMouseEvent::Button::kRight; else if (event->buttons() & Qt::MidButton) - return WebMouseEvent::Button::Middle; + return WebMouseEvent::Button::kMiddle; - return WebMouseEvent::Button::NoButton; + return WebMouseEvent::Button::kNoButton; } template <typename T> @@ -1061,11 +1061,11 @@ static unsigned mouseButtonsModifiersForEvent(const T* event) { unsigned ret = 0; if (event->buttons() & Qt::LeftButton) - ret |= WebInputEvent::LeftButtonDown; + ret |= WebInputEvent::kLeftButtonDown; if (event->buttons() & Qt::RightButton) - ret |= WebInputEvent::RightButtonDown; + ret |= WebInputEvent::kRightButtonDown; if (event->buttons() & Qt::MidButton) - ret |= WebInputEvent::MiddleButtonDown; + ret |= WebInputEvent::kMiddleButtonDown; return ret; } @@ -1075,19 +1075,19 @@ static inline WebInputEvent::Modifiers modifierForKeyCode(int key) { switch (key) { case Qt::Key_Shift: - return WebInputEvent::ShiftKey; + return WebInputEvent::kShiftKey; case Qt::Key_Alt: - return WebInputEvent::AltKey; + return WebInputEvent::kAltKey; #if defined(Q_OS_OSX) case Qt::Key_Control: - return (!qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) ? WebInputEvent::MetaKey : WebInputEvent::ControlKey; + return (!qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) ? WebInputEvent::kMetaKey : WebInputEvent::kControlKey; case Qt::Key_Meta: - return (!qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) ? WebInputEvent::ControlKey : WebInputEvent::MetaKey; + return (!qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) ? WebInputEvent::kControlKey : WebInputEvent::kMetaKey; #else case Qt::Key_Control: - return WebInputEvent::ControlKey; + return WebInputEvent::kControlKey; case Qt::Key_Meta: - return WebInputEvent::MetaKey; + return WebInputEvent::kMetaKey; #endif default: return static_cast<WebInputEvent::Modifiers>(0); @@ -1101,24 +1101,24 @@ static inline WebInputEvent::Modifiers modifiersForEvent(const QInputEvent* even #if defined(Q_OS_OSX) if (!qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) { if (modifiers & Qt::ControlModifier) - result |= WebInputEvent::MetaKey; + result |= WebInputEvent::kMetaKey; if (modifiers & Qt::MetaModifier) - result |= WebInputEvent::ControlKey; + result |= WebInputEvent::kControlKey; } else #endif { if (modifiers & Qt::ControlModifier) - result |= WebInputEvent::ControlKey; + result |= WebInputEvent::kControlKey; if (modifiers & Qt::MetaModifier) - result |= WebInputEvent::MetaKey; + result |= WebInputEvent::kMetaKey; } if (modifiers & Qt::ShiftModifier) - result |= WebInputEvent::ShiftKey; + result |= WebInputEvent::kShiftKey; if (modifiers & Qt::AltModifier) - result |= WebInputEvent::AltKey; + result |= WebInputEvent::kAltKey; if (modifiers & Qt::KeypadModifier) - result |= WebInputEvent::IsKeyPad; + result |= WebInputEvent::kIsKeyPad; switch (event->type()) { case QEvent::MouseButtonPress: @@ -1133,7 +1133,7 @@ static inline WebInputEvent::Modifiers modifiersForEvent(const QInputEvent* even case QEvent::KeyRelease: { const QKeyEvent *keyEvent = static_cast<const QKeyEvent*>(event); if (keyEvent->isAutoRepeat()) - result |= WebInputEvent::IsAutoRepeat; + result |= WebInputEvent::kIsAutoRepeat; result |= modifierForKeyCode(keyEvent->key()); } default: @@ -1147,51 +1147,49 @@ static WebInputEvent::Type webEventTypeForEvent(const QEvent* event) { switch (event->type()) { case QEvent::MouseButtonPress: - return WebInputEvent::MouseDown; + return WebInputEvent::kMouseDown; case QEvent::MouseButtonRelease: - return WebInputEvent::MouseUp; + return WebInputEvent::kMouseUp; case QEvent::Enter: - return WebInputEvent::MouseEnter; + return WebInputEvent::kMouseEnter; case QEvent::Leave: - return WebInputEvent::MouseLeave; + return WebInputEvent::kMouseLeave; case QEvent::MouseMove: - return WebInputEvent::MouseMove; + return WebInputEvent::kMouseMove; case QEvent::Wheel: - return WebInputEvent::MouseWheel; + return WebInputEvent::kMouseWheel; case QEvent::KeyPress: - return WebInputEvent::RawKeyDown; + return WebInputEvent::kRawKeyDown; case QEvent::KeyRelease: - return WebInputEvent::KeyUp; + return WebInputEvent::kKeyUp; case QEvent::HoverMove: - return WebInputEvent::MouseMove; + return WebInputEvent::kMouseMove; case QEvent::TouchBegin: - return WebInputEvent::TouchStart; + return WebInputEvent::kTouchStart; case QEvent::TouchUpdate: - return WebInputEvent::TouchMove; + return WebInputEvent::kTouchMove; case QEvent::TouchEnd: - return WebInputEvent::TouchEnd; + return WebInputEvent::kTouchEnd; case QEvent::TouchCancel: - return WebInputEvent::TouchCancel; + return WebInputEvent::kTouchCancel; default: Q_ASSERT(false); - return WebInputEvent::MouseMove; + return WebInputEvent::kMouseMove; } } WebMouseEvent WebEventFactory::toWebMouseEvent(QMouseEvent *ev, double dpiScale) { - WebMouseEvent webKitEvent; - webKitEvent.timeStampSeconds = currentTimeForEvent(ev); - webKitEvent.button = mouseButtonForEvent(ev); - webKitEvent.modifiers = modifiersForEvent(ev); - - webKitEvent.x = webKitEvent.windowX = ev->x() / dpiScale; - webKitEvent.y = webKitEvent.windowY = ev->y() / dpiScale; - webKitEvent.globalX = ev->globalX(); - webKitEvent.globalY = ev->globalY(); + WebMouseEvent webKitEvent(webEventTypeForEvent(ev), + ev->x() / dpiScale, + ev->y() / dpiScale, + ev->globalX(), + ev->globalY(), + modifiersForEvent(ev), + currentTimeForEvent(ev)); - webKitEvent.type = webEventTypeForEvent(ev); - webKitEvent.clickCount = 0; + webKitEvent.button = mouseButtonForEvent(ev); + webKitEvent.click_count = 0; return webKitEvent; } @@ -1199,15 +1197,14 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QMouseEvent *ev, double dpiScale) WebMouseEvent WebEventFactory::toWebMouseEvent(QHoverEvent *ev, double dpiScale) { WebMouseEvent webKitEvent; - webKitEvent.timeStampSeconds = currentTimeForEvent(ev); - webKitEvent.modifiers = modifiersForEvent(ev); + webKitEvent.SetTimeStampSeconds(currentTimeForEvent(ev)); + webKitEvent.SetModifiers(modifiersForEvent(ev)); + webKitEvent.SetType(webEventTypeForEvent(ev)); - webKitEvent.x = webKitEvent.windowX = ev->pos().x() / dpiScale; - webKitEvent.y = webKitEvent.windowY = ev->pos().y() / dpiScale; - webKitEvent.movementX = ev->pos().x() - ev->oldPos().x(); - webKitEvent.movementY = ev->pos().y() - ev->oldPos().y(); + webKitEvent.SetPositionInWidget(ev->pos().x() / dpiScale, ev->pos().y() / dpiScale); + webKitEvent.movement_x = ev->pos().x() - ev->oldPos().x(); + webKitEvent.movement_y = ev->pos().y() - ev->oldPos().y(); - webKitEvent.type = webEventTypeForEvent(ev); return webKitEvent; } @@ -1215,26 +1212,26 @@ WebMouseEvent WebEventFactory::toWebMouseEvent(QHoverEvent *ev, double dpiScale) WebGestureEvent WebEventFactory::toWebGestureEvent(QNativeGestureEvent *ev, double dpiScale) { WebGestureEvent webKitEvent; - webKitEvent.timeStampSeconds = currentTimeForEvent(ev); - webKitEvent.modifiers = modifiersForEvent(ev); + webKitEvent.SetTimeStampSeconds(currentTimeForEvent(ev)); + webKitEvent.SetModifiers(modifiersForEvent(ev)); webKitEvent.x = static_cast<int>(ev->localPos().x() / dpiScale); webKitEvent.y = static_cast<int>(ev->localPos().y() / dpiScale); - webKitEvent.globalX = static_cast<int>(ev->screenPos().x() / dpiScale); - webKitEvent.globalY = static_cast<int>(ev->screenPos().y() / dpiScale); + webKitEvent.global_x = static_cast<int>(ev->screenPos().x() / dpiScale); + webKitEvent.global_y = static_cast<int>(ev->screenPos().y() / dpiScale); - webKitEvent.sourceDevice = blink::WebGestureDeviceTouchpad; + webKitEvent.source_device = blink::kWebGestureDeviceTouchpad; Qt::NativeGestureType gestureType = ev->gestureType(); switch (gestureType) { case Qt::ZoomNativeGesture: - webKitEvent.type = WebInputEvent::GesturePinchUpdate; - webKitEvent.data.pinchUpdate.scale = static_cast<float>(ev->value() + 1.0); + webKitEvent.SetType(WebInputEvent::kGesturePinchUpdate); + webKitEvent.data.pinch_update.scale = static_cast<float>(ev->value() + 1.0); break; case Qt::SmartZoomNativeGesture: - webKitEvent.type = WebInputEvent::GestureDoubleTap; - webKitEvent.data.tap.tapCount = 1; + webKitEvent.SetType(WebInputEvent::kGestureDoubleTap); + webKitEvent.data.tap.tap_count = 1; break; case Qt::BeginNativeGesture: case Qt::EndNativeGesture: @@ -1242,7 +1239,7 @@ WebGestureEvent WebEventFactory::toWebGestureEvent(QNativeGestureEvent *ev, doub case Qt::PanNativeGesture: case Qt::SwipeNativeGesture: // Not implemented by Chromium for now. - webKitEvent.type = blink::WebInputEvent::Undefined; + webKitEvent.SetType(blink::WebInputEvent::kUndefined); break; } @@ -1253,58 +1250,62 @@ WebGestureEvent WebEventFactory::toWebGestureEvent(QNativeGestureEvent *ev, doub blink::WebMouseWheelEvent WebEventFactory::toWebWheelEvent(QWheelEvent *ev, double dpiScale) { WebMouseWheelEvent webEvent; - webEvent.type = webEventTypeForEvent(ev); - webEvent.deltaX = 0; - webEvent.deltaY = 0; - webEvent.wheelTicksX = 0; - webEvent.wheelTicksY = 0; - webEvent.modifiers = modifiersForEvent(ev); - webEvent.timeStampSeconds = currentTimeForEvent(ev); + webEvent.delta_x = 0; + webEvent.delta_y = 0; + webEvent.wheel_ticks_x = 0; + webEvent.wheel_ticks_y = 0; + webEvent.SetType(webEventTypeForEvent(ev)); + webEvent.SetModifiers(modifiersForEvent(ev)); + webEvent.SetTimeStampSeconds(currentTimeForEvent(ev)); - webEvent.wheelTicksX = static_cast<float>(ev->angleDelta().x()) / QWheelEvent::DefaultDeltasPerStep; - webEvent.wheelTicksY = static_cast<float>(ev->angleDelta().y()) / QWheelEvent::DefaultDeltasPerStep; + webEvent.wheel_ticks_x = static_cast<float>(ev->angleDelta().x()) / QWheelEvent::DefaultDeltasPerStep; + webEvent.wheel_ticks_y = static_cast<float>(ev->angleDelta().y()) / QWheelEvent::DefaultDeltasPerStep; // We can't use the device specific QWheelEvent::pixelDelta(), so we calculate // a pixel delta based on ticks and scroll per line. static const float cDefaultQtScrollStep = 20.f; - webEvent.deltaX = webEvent.wheelTicksX * wheelScrollLines * cDefaultQtScrollStep; - webEvent.deltaY = webEvent.wheelTicksY * wheelScrollLines * cDefaultQtScrollStep; +#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) + const int wheelScrollLines = QGuiApplication::styleHints()->wheelScrollLines(); +#else + const int wheelScrollLines = 3; +#endif + webEvent.delta_x = webEvent.wheel_ticks_x * wheelScrollLines * cDefaultQtScrollStep; + webEvent.delta_y = webEvent.wheel_ticks_y * wheelScrollLines * cDefaultQtScrollStep; + + webEvent.SetPositionInWidget(ev->x() / dpiScale, ev->y() / dpiScale); + webEvent.SetPositionInScreen(ev->globalX(), ev->globalY()); - webEvent.x = webEvent.windowX = ev->x() / dpiScale; - webEvent.y = webEvent.windowY = ev->y() / dpiScale; - webEvent.globalX = ev->globalX(); - webEvent.globalY = ev->globalY(); return webEvent; } content::NativeWebKeyboardEvent WebEventFactory::toWebKeyboardEvent(QKeyEvent *ev) { content::NativeWebKeyboardEvent webKitEvent(reinterpret_cast<gfx::NativeEvent>(ev)); - webKitEvent.timeStampSeconds = currentTimeForEvent(ev); - webKitEvent.modifiers = modifiersForEvent(ev); - webKitEvent.type = webEventTypeForEvent(ev); + webKitEvent.SetTimeStampSeconds(currentTimeForEvent(ev)); + webKitEvent.SetModifiers(modifiersForEvent(ev)); + webKitEvent.SetType(webEventTypeForEvent(ev)); - webKitEvent.nativeKeyCode = ev->nativeVirtualKey(); - webKitEvent.windowsKeyCode = windowsKeyCodeForKeyEvent(ev->key(), ev->modifiers() & Qt::KeypadModifier); - webKitEvent.domKey = getDomKeyFromQKeyEvent(ev); + webKitEvent.native_key_code = ev->nativeVirtualKey(); + webKitEvent.windows_key_code = windowsKeyCodeForKeyEvent(ev->key(), ev->modifiers() & Qt::KeypadModifier); + webKitEvent.dom_key = getDomKeyFromQKeyEvent(ev); ui::DomCode domCode = ui::DomCode::NONE; int scanCode = ev->nativeScanCode(); if (scanCode) domCode = ui::KeycodeConverter::NativeKeycodeToDomCode(scanCode); - webKitEvent.domCode = static_cast<int>(domCode); + webKitEvent.dom_code = static_cast<int>(domCode); const ushort* text = ev->text().utf16(); memcpy(&webKitEvent.text, text, std::min(sizeof(webKitEvent.text), size_t(ev->text().length() * 2))); - memcpy(&webKitEvent.unmodifiedText, text, std::min(sizeof(webKitEvent.unmodifiedText), size_t(ev->text().length() * 2))); + memcpy(&webKitEvent.unmodified_text, text, std::min(sizeof(webKitEvent.unmodified_text), size_t(ev->text().length() * 2))); - if (webKitEvent.windowsKeyCode == VK_RETURN) { + if (webKitEvent.windows_key_code == VK_RETURN) { // This is the same behavior as GTK: // We need to treat the enter key as a key press of character \r. This // is apparently just how webkit handles it and what it expects. - webKitEvent.unmodifiedText[0] = '\r'; - webKitEvent.text[0] = webKitEvent.unmodifiedText[0]; + webKitEvent.unmodified_text[0] = '\r'; + webKitEvent.text[0] = webKitEvent.unmodified_text[0]; } return webKitEvent; diff --git a/src/core/web_event_factory.h b/src/core/web_event_factory.h index 859e97643..259795c1f 100644 --- a/src/core/web_event_factory.h +++ b/src/core/web_event_factory.h @@ -41,10 +41,11 @@ #define WEB_EVENT_FACTORY_H #include "content/public/browser/native_web_keyboard_event.h" -#include "third_party/WebKit/public/platform/WebInputEvent.h" #ifndef QT_NO_GESTURES #include "third_party/WebKit/public/platform/WebGestureEvent.h" #endif +#include "third_party/WebKit/public/platform/WebMouseEvent.h" +#include "third_party/WebKit/public/platform/WebMouseWheelEvent.h" #include <QtGlobal> |