diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/config/desktop_linux.pri | 8 | ||||
-rw-r--r-- | src/core/core_gyp_generator.pro | 2 | ||||
-rw-r--r-- | src/core/core_module.pro | 2 | ||||
-rw-r--r-- | src/core/gl_surface_qt.cpp | 82 | ||||
-rw-r--r-- | src/core/gyp_run.pro | 1 | ||||
-rw-r--r-- | src/core/location_provider_qt.cpp | 34 | ||||
-rw-r--r-- | src/core/render_widget_host_view_qt.cpp | 6 | ||||
-rw-r--r-- | src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.cpp | 401 | ||||
-rw-r--r-- | src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.h | 108 | ||||
-rw-r--r-- | src/core/renderer/pepper/pepper_host_factory_qt.cpp | 24 | ||||
-rw-r--r-- | src/webengine/doc/src/qtwebengine-features.qdoc | 2 | ||||
-rw-r--r-- | src/webengine/doc/src/qtwebengine-overview.qdoc | 12 | ||||
-rw-r--r-- | src/webengine/doc/src/qtwebengine-platform-notes.qdoc | 1 | ||||
-rw-r--r-- | src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc | 3 |
14 files changed, 648 insertions, 38 deletions
diff --git a/src/core/config/desktop_linux.pri b/src/core/config/desktop_linux.pri index a78082581..de0fbbc6b 100644 --- a/src/core/config/desktop_linux.pri +++ b/src/core/config/desktop_linux.pri @@ -6,5 +6,9 @@ GYP_CONFIG += \ desktop_linux=1 \ enable_widevine=1 -linux-clang: GYP_CONFIG += clang=1 host_clang=1 clang_use_chrome_plugins=0 make_clang_dir=/usr -else: GYP_CONFIG += clang=0 host_clang=0 +clang { + GYP_CONFIG += clang=1 host_clang=1 clang_use_chrome_plugins=0 make_clang_dir=/usr + linux-clang-libc++: GYP_CONFIG += use_system_libcxx=1 +} else { + GYP_CONFIG += clang=0 host_clang=0 +} diff --git a/src/core/core_gyp_generator.pro b/src/core/core_gyp_generator.pro index 3e6a9eac0..cdff4ed64 100644 --- a/src/core/core_gyp_generator.pro +++ b/src/core/core_gyp_generator.pro @@ -73,6 +73,7 @@ SOURCES = \ render_widget_host_view_qt.cpp \ renderer/content_renderer_client_qt.cpp \ renderer/pepper/pepper_flash_browser_host_qt.cpp \ + renderer/pepper/pepper_flash_clipboard_message_filter_qt.cpp \ renderer/pepper/pepper_flash_renderer_host_qt.cpp \ renderer/pepper/pepper_host_factory_qt.cpp \ renderer/pepper/pepper_isolated_file_system_message_filter.cpp \ @@ -155,6 +156,7 @@ HEADERS = \ render_widget_host_view_qt_delegate.h \ renderer/content_renderer_client_qt.h \ renderer/pepper/pepper_flash_browser_host_qt.h \ + renderer/pepper/pepper_flash_clipboard_message_filter_qt.h \ renderer/pepper/pepper_flash_renderer_host_qt.h \ renderer/pepper/pepper_host_factory_qt.h \ renderer/pepper/pepper_isolated_file_system_message_filter.h \ diff --git a/src/core/core_module.pro b/src/core/core_module.pro index fa402cc63..702b92441 100644 --- a/src/core/core_module.pro +++ b/src/core/core_module.pro @@ -14,6 +14,8 @@ load(qt_module) api_library_name = qtwebenginecoreapi$$qtPlatformTargetSuffix() api_library_path = $$OUT_PWD/api/$$getConfigDir() +# Do not precompile any headers. We are only interested in the linker step. +PRECOMPILED_HEADER = LIBS_PRIVATE += -L$$api_library_path CONFIG *= no_smart_library_merge diff --git a/src/core/gl_surface_qt.cpp b/src/core/gl_surface_qt.cpp index 8283e4cc4..f499d853e 100644 --- a/src/core/gl_surface_qt.cpp +++ b/src/core/gl_surface_qt.cpp @@ -87,6 +87,7 @@ void* g_display; const char* g_extensions = NULL; +bool g_egl_surfaceless_context_supported = false; } // namespace @@ -109,6 +110,26 @@ private: DISALLOW_COPY_AND_ASSIGN(GLSurfaceQtEGL); }; +// The following comment is cited from chromium/ui/gl/gl_surface_egl.cc: +// SurfacelessEGL is used as Offscreen surface when platform supports +// KHR_surfaceless_context and GL_OES_surfaceless_context. This would avoid the +// need to create a dummy EGLsurface in case we render to client API targets. +class GLSurfacelessQtEGL : public GLSurfaceQt { +public: + explicit GLSurfacelessQtEGL(const gfx::Size& size); + + public: + bool Initialize() Q_DECL_OVERRIDE; + void Destroy() Q_DECL_OVERRIDE; + bool IsSurfaceless() const Q_DECL_OVERRIDE; + bool Resize(const gfx::Size& size, float scale_factor, bool has_alpha) Q_DECL_OVERRIDE; + EGLSurface GetHandle() Q_DECL_OVERRIDE; + void* GetShareHandle() Q_DECL_OVERRIDE; + +private: + DISALLOW_COPY_AND_ASSIGN(GLSurfacelessQtEGL); +}; + GLSurfaceQt::~GLSurfaceQt() { @@ -342,6 +363,23 @@ bool GLSurfaceQtEGL::InitializeOneOff() return false; } + g_egl_surfaceless_context_supported = ExtensionsContain(g_extensions, "EGL_KHR_surfaceless_context"); + if (g_egl_surfaceless_context_supported) { + scoped_refptr<GLSurface> surface = new GLSurfacelessQtEGL(Size(1, 1)); + scoped_refptr<GLContext> context = GLContext::CreateGLContext( + NULL, surface.get(), PreferIntegratedGpu); + + if (!context->MakeCurrent(surface.get())) + g_egl_surfaceless_context_supported = false; + + // Ensure context supports GL_OES_surfaceless_context. + if (g_egl_surfaceless_context_supported) { + g_egl_surfaceless_context_supported = context->HasExtension( + "GL_OES_surfaceless_context"); + context->ReleaseCurrent(surface.get()); + } + } + initialized = true; return true; } @@ -426,7 +464,7 @@ bool GLSurfaceQtEGL::Initialize() g_config, pbuffer_attributes); if (!m_surfaceBuffer) { - LOG(ERROR) << "eglCreatePbufferSurface failed with error ", GetLastEGLErrorString(); + LOG(ERROR) << "eglCreatePbufferSurface failed with error " << GetLastEGLErrorString(); Destroy(); return false; } @@ -502,6 +540,41 @@ void* GLSurfaceQt::GetConfig() return g_config; } +GLSurfacelessQtEGL::GLSurfacelessQtEGL(const gfx::Size& size) + : GLSurfaceQt(size) +{ +} + +bool GLSurfacelessQtEGL::Initialize() +{ + return true; +} + +void GLSurfacelessQtEGL::Destroy() +{ +} + +bool GLSurfacelessQtEGL::IsSurfaceless() const +{ + return true; +} + +bool GLSurfacelessQtEGL::Resize(const gfx::Size& size, float scale_factor, bool has_alpha) +{ + m_size = size; + return true; +} + +EGLSurface GLSurfacelessQtEGL::GetHandle() +{ + return EGL_NO_SURFACE; +} + +void* GLSurfacelessQtEGL::GetShareHandle() +{ + return NULL; +} + // static scoped_refptr<GLSurface> GLSurface::CreateOffscreenGLSurface(const gfx::Size& size) @@ -525,7 +598,12 @@ GLSurface::CreateOffscreenGLSurface(const gfx::Size& size) #endif } case kGLImplementationEGLGLES2: { - scoped_refptr<GLSurface> surface = new GLSurfaceQtEGL(size); + scoped_refptr<GLSurface> surface; + if (g_egl_surfaceless_context_supported) + surface = new GLSurfacelessQtEGL(size); + else + surface = new GLSurfaceQtEGL(size); + if (!surface->Initialize()) return NULL; return surface; diff --git a/src/core/gyp_run.pro b/src/core/gyp_run.pro index 41cdf4598..35b85b4c7 100644 --- a/src/core/gyp_run.pro +++ b/src/core/gyp_run.pro @@ -82,6 +82,7 @@ contains(QT_ARCH, "arm") { else: GYP_CONFIG += arm_fpu=\"$$MFPU\" arm_neon=0 arm_neon_optional=0 } + contains(QMAKE_CFLAGS, "-marm"): GYP_CONFIG += arm_thumb=0 contains(QMAKE_CFLAGS, "-mthumb"): GYP_CONFIG += arm_thumb=1 } diff --git a/src/core/location_provider_qt.cpp b/src/core/location_provider_qt.cpp index cc87d8417..c07bd4b0c 100644 --- a/src/core/location_provider_qt.cpp +++ b/src/core/location_provider_qt.cpp @@ -44,11 +44,13 @@ #include "type_conversion.h" #include <QtCore/QCoreApplication> +#include <QtCore/QMetaObject> #include <QtCore/QThread> #include <QtPositioning/QGeoPositionInfoSource> -#include "base/message_loop/message_loop.h" #include "base/bind.h" +#include "base/memory/weak_ptr.h" +#include "base/message_loop/message_loop.h" #include "content/browser/geolocation/geolocation_provider_impl.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/geolocation_provider.h" @@ -63,9 +65,9 @@ public: QtPositioningHelper(LocationProviderQt *provider); ~QtPositioningHelper(); - void start(bool highAccuracy); - void stop(); - void refresh(); + Q_INVOKABLE void start(bool highAccuracy); + Q_INVOKABLE void stop(); + Q_INVOKABLE void refresh(); private Q_SLOTS: void updatePosition(const QGeoPositionInfo &); @@ -75,6 +77,7 @@ private Q_SLOTS: private: LocationProviderQt *m_locationProvider; QGeoPositionInfoSource *m_positionInfoSource; + base::WeakPtrFactory<LocationProviderQt> m_locationProviderFactory; void postToLocationProvider(const base::Closure &task); friend class LocationProviderQt; @@ -83,14 +86,13 @@ private: QtPositioningHelper::QtPositioningHelper(LocationProviderQt *provider) : m_locationProvider(provider) , m_positionInfoSource(0) + , m_locationProviderFactory(provider) { Q_ASSERT(provider); } QtPositioningHelper::~QtPositioningHelper() { - if (m_locationProvider) - m_locationProvider->m_positioningHelper = 0; } static bool isHighAccuracySource(const QGeoPositionInfoSource *source) @@ -186,7 +188,8 @@ void QtPositioningHelper::updatePosition(const QGeoPositionInfo &pos) newPos.speed = pos.hasAttribute(QGeoPositionInfo::GroundSpeed) ? pos.attribute(QGeoPositionInfo::GroundSpeed) : -1; newPos.heading = pos.hasAttribute(QGeoPositionInfo::Direction) ? pos.attribute(QGeoPositionInfo::Direction) : -1; - postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, base::Unretained(m_locationProvider), newPos)); + if (m_locationProvider) + postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, m_locationProviderFactory.GetWeakPtr(), newPos)); } void QtPositioningHelper::error(QGeoPositionInfoSource::Error positioningError) @@ -203,7 +206,8 @@ void QtPositioningHelper::error(QGeoPositionInfoSource::Error positioningError) newPos.error_code = content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; break; } - postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, base::Unretained(m_locationProvider), newPos)); + if (m_locationProvider) + postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, m_locationProviderFactory.GetWeakPtr(), newPos)); } void QtPositioningHelper::timeout() @@ -213,7 +217,8 @@ void QtPositioningHelper::timeout() // argument used in JS never comes all the way to the browser process. // Let's just treat it like any other error where the position is unavailable. newPos.error_code = content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; - postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, base::Unretained(m_locationProvider), newPos)); + if (m_locationProvider) + postToLocationProvider(base::Bind(&LocationProviderQt::updatePosition, m_locationProviderFactory.GetWeakPtr(), newPos)); } inline void QtPositioningHelper::postToLocationProvider(const base::Closure &task) @@ -230,6 +235,7 @@ LocationProviderQt::~LocationProviderQt() { if (m_positioningHelper) { m_positioningHelper->m_locationProvider = 0; + m_positioningHelper->m_locationProviderFactory.InvalidateWeakPtrs(); m_positioningHelper->deleteLater(); } } @@ -241,23 +247,21 @@ bool LocationProviderQt::StartProvider(bool highAccuracy) m_positioningHelper = new QtPositioningHelper(this); m_positioningHelper->moveToThread(guiThread); } - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(&QtPositioningHelper::start - , base::Unretained(m_positioningHelper), highAccuracy)); + + QMetaObject::invokeMethod(m_positioningHelper, "start", Qt::QueuedConnection, Q_ARG(bool, highAccuracy)); return true; } void LocationProviderQt::StopProvider() { if (m_positioningHelper) - BrowserThread::PostTask(BrowserThread::UI,FROM_HERE, base::Bind(&QtPositioningHelper::stop - , base::Unretained(m_positioningHelper))); + QMetaObject::invokeMethod(m_positioningHelper, "stop", Qt::QueuedConnection); } void LocationProviderQt::RequestRefresh() { if (m_positioningHelper) - BrowserThread::PostTask(BrowserThread::UI,FROM_HERE, base::Bind(&QtPositioningHelper::refresh - , base::Unretained(m_positioningHelper))); + QMetaObject::invokeMethod(m_positioningHelper, "refresh", Qt::QueuedConnection); } void LocationProviderQt::OnPermissionGranted() diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp index 27eda06a6..a78e3a2c3 100644 --- a/src/core/render_widget_host_view_qt.cpp +++ b/src/core/render_widget_host_view_qt.cpp @@ -834,12 +834,12 @@ void RenderWidgetHostViewQt::sendDelegatedFrameAck() void RenderWidgetHostViewQt::processMotionEvent(const ui::MotionEvent &motionEvent) { - if (!m_gestureProvider.OnTouchEvent(motionEvent).succeeded) + auto result = m_gestureProvider.OnTouchEvent(motionEvent); + if (!result.succeeded) return; - bool causesScrollingIfUncancelled = true; blink::WebTouchEvent touchEvent = ui::CreateWebTouchEventFromMotionEvent(motionEvent, - causesScrollingIfUncancelled); + result.did_generate_scroll); m_host->ForwardTouchEventWithLatencyInfo(touchEvent, CreateLatencyInfo(touchEvent)); } diff --git a/src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.cpp b/src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.cpp new file mode 100644 index 000000000..c1782844d --- /dev/null +++ b/src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.cpp @@ -0,0 +1,401 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// based on chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.cc +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "pepper_flash_clipboard_message_filter_qt.h" + +#include "base/pickle.h" +#include "base/strings/utf_string_conversions.h" +#include "content/public/browser/browser_thread.h" +#include "ipc/ipc_message.h" +#include "ipc/ipc_message_macros.h" +#include "ppapi/c/pp_errors.h" +#include "ppapi/c/private/ppb_flash_clipboard.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/host_message_context.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/resource_message_params.h" +#include "ui/base/clipboard/scoped_clipboard_writer.h" + +using content::BrowserThread; + +namespace QtWebEngineCore { + +namespace { + +const size_t kMaxClipboardWriteSize = 1000000; + +ui::ClipboardType ConvertClipboardType(uint32_t type) +{ + switch (type) { + case PP_FLASH_CLIPBOARD_TYPE_STANDARD: + return ui::CLIPBOARD_TYPE_COPY_PASTE; + case PP_FLASH_CLIPBOARD_TYPE_SELECTION: + return ui::CLIPBOARD_TYPE_SELECTION; + } + NOTREACHED(); + return ui::CLIPBOARD_TYPE_COPY_PASTE; +} + +// Functions to pack/unpack custom data from a pickle. See the header file for +// more detail on custom formats in Pepper. +// TODO(raymes): Currently pepper custom formats are stored in their own +// native format type. However we should be able to store them in the same way +// as "Web Custom" formats are. This would allow clipboard data to be shared +// between pepper applications and web applications. However currently web apps +// assume all data that is placed on the clipboard is UTF16 and pepper allows +// arbitrary data so this change would require some reworking of the chrome +// clipboard interface for custom data. +bool JumpToFormatInPickle(const base::string16& format, base::PickleIterator* iter) +{ + size_t size = 0; + if (!iter->ReadSizeT(&size)) + return false; + for (size_t i = 0; i < size; ++i) { + base::string16 stored_format; + if (!iter->ReadString16(&stored_format)) + return false; + if (stored_format == format) + return true; + int skip_length; + if (!iter->ReadLength(&skip_length)) + return false; + if (!iter->SkipBytes(skip_length)) + return false; + } + return false; +} + +bool IsFormatAvailableInPickle(const base::string16& format, const base::Pickle& pickle) +{ + base::PickleIterator iter(pickle); + return JumpToFormatInPickle(format, &iter); +} + +std::string ReadDataFromPickle(const base::string16& format, const base::Pickle& pickle) +{ + std::string result; + base::PickleIterator iter(pickle); + if (!JumpToFormatInPickle(format, &iter) || !iter.ReadString(&result)) + return std::string(); + return result; +} + +bool WriteDataToPickle(const std::map<base::string16, std::string>& data, base::Pickle* pickle) +{ + pickle->WriteSizeT(data.size()); + for (std::map<base::string16, std::string>::const_iterator it = data.begin(); it != data.end(); ++it) { + if (!pickle->WriteString16(it->first)) + return false; + if (!pickle->WriteString(it->second)) + return false; + } + return true; +} + +} // namespace + +PepperFlashClipboardMessageFilter::PepperFlashClipboardMessageFilter() {} + +PepperFlashClipboardMessageFilter::~PepperFlashClipboardMessageFilter() {} + +scoped_refptr<base::TaskRunner> +PepperFlashClipboardMessageFilter::OverrideTaskRunnerForMessage(const IPC::Message& msg) +{ + // Clipboard writes should always occur on the UI thread due to the + // restrictions of various platform APIs. In general, the clipboard is not + // thread-safe, so all clipboard calls should be serviced from the UI thread. + if (msg.type() == PpapiHostMsg_FlashClipboard_WriteData::ID) + return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); + + // Windows needs clipboard reads to be serviced from the IO thread because + // these are sync IPCs which can result in deadlocks with plugins if serviced + // from the UI thread. Note that Windows clipboard calls ARE thread-safe so it + // is ok for reads and writes to be serviced from different threads. +#if !defined(OS_WIN) + return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); +#else + return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); +#endif +} + +int32_t PepperFlashClipboardMessageFilter::OnResourceMessageReceived(const IPC::Message& msg, + ppapi::host::HostMessageContext* context) +{ + PPAPI_BEGIN_MESSAGE_MAP(PepperFlashClipboardMessageFilter, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashClipboard_RegisterCustomFormat, + OnMsgRegisterCustomFormat) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashClipboard_IsFormatAvailable, + OnMsgIsFormatAvailable) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashClipboard_ReadData, + OnMsgReadData) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashClipboard_WriteData, + OnMsgWriteData) + PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashClipboard_GetSequenceNumber, + OnMsgGetSequenceNumber) + PPAPI_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t PepperFlashClipboardMessageFilter::OnMsgRegisterCustomFormat( + ppapi::host::HostMessageContext* host_context, + const std::string& format_name) +{ + uint32_t format = m_custom_formats.RegisterFormat(format_name); + if (format == PP_FLASH_CLIPBOARD_FORMAT_INVALID) + return PP_ERROR_FAILED; + host_context->reply_msg = PpapiPluginMsg_FlashClipboard_RegisterCustomFormatReply(format); + return PP_OK; +} + +int32_t PepperFlashClipboardMessageFilter::OnMsgIsFormatAvailable( + ppapi::host::HostMessageContext* host_context, + uint32_t clipboard_type, + uint32_t format) +{ + if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) { + NOTIMPLEMENTED(); + return PP_ERROR_FAILED; + } + + ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); + ui::ClipboardType type = ConvertClipboardType(clipboard_type); + bool available = false; + switch (format) { + case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: { + bool plain = clipboard->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(), type); + bool plainw = clipboard->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(), type); + available = plain || plainw; + break; + } + case PP_FLASH_CLIPBOARD_FORMAT_HTML: + available = clipboard->IsFormatAvailable(ui::Clipboard::GetHtmlFormatType(), type); + break; + case PP_FLASH_CLIPBOARD_FORMAT_RTF: + available = clipboard->IsFormatAvailable(ui::Clipboard::GetRtfFormatType(), type); + break; + case PP_FLASH_CLIPBOARD_FORMAT_INVALID: + break; + default: + if (m_custom_formats.IsFormatRegistered(format)) { + std::string format_name = m_custom_formats.GetFormatName(format); + std::string clipboard_data; + clipboard->ReadData(ui::Clipboard::GetPepperCustomDataFormatType(), &clipboard_data); + base::Pickle pickle(clipboard_data.data(), clipboard_data.size()); + available = IsFormatAvailableInPickle(base::UTF8ToUTF16(format_name), pickle); + } + break; + } + + return available ? PP_OK : PP_ERROR_FAILED; +} + +int32_t PepperFlashClipboardMessageFilter::OnMsgReadData( + ppapi::host::HostMessageContext* host_context, + uint32_t clipboard_type, + uint32_t format) +{ + if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) { + NOTIMPLEMENTED(); + return PP_ERROR_FAILED; + } + + ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); + ui::ClipboardType type = ConvertClipboardType(clipboard_type); + std::string clipboard_string; + int32_t result = PP_ERROR_FAILED; + switch (format) { + case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: { + if (clipboard->IsFormatAvailable(ui::Clipboard::GetPlainTextWFormatType(), type)) { + base::string16 text; + clipboard->ReadText(type, &text); + if (!text.empty()) { + result = PP_OK; + clipboard_string = base::UTF16ToUTF8(text); + break; + } + } + // If the PlainTextW format isn't available or is empty, take the + // ASCII text format. + if (clipboard->IsFormatAvailable(ui::Clipboard::GetPlainTextFormatType(), type)) { + result = PP_OK; + clipboard->ReadAsciiText(type, &clipboard_string); + } + break; + } + case PP_FLASH_CLIPBOARD_FORMAT_HTML: { + if (!clipboard->IsFormatAvailable(ui::Clipboard::GetHtmlFormatType(), type)) { + break; + } + + base::string16 html; + std::string url; + uint32_t fragment_start; + uint32_t fragment_end; + clipboard->ReadHTML(type, &html, &url, &fragment_start, &fragment_end); + result = PP_OK; + clipboard_string = base::UTF16ToUTF8(html.substr(fragment_start, fragment_end - fragment_start)); + break; + } + case PP_FLASH_CLIPBOARD_FORMAT_RTF: { + if (!clipboard->IsFormatAvailable(ui::Clipboard::GetRtfFormatType(), type)) { + break; + } + result = PP_OK; + clipboard->ReadRTF(type, &clipboard_string); + break; + } + case PP_FLASH_CLIPBOARD_FORMAT_INVALID: + break; + default: + if (m_custom_formats.IsFormatRegistered(format)) { + base::string16 format_name = + base::UTF8ToUTF16(m_custom_formats.GetFormatName(format)); + std::string clipboard_data; + clipboard->ReadData(ui::Clipboard::GetPepperCustomDataFormatType(), + &clipboard_data); + base::Pickle pickle(clipboard_data.data(), clipboard_data.size()); + if (IsFormatAvailableInPickle(format_name, pickle)) { + result = PP_OK; + clipboard_string = ReadDataFromPickle(format_name, pickle); + } + } + break; + } + + if (result == PP_OK) { + host_context->reply_msg = PpapiPluginMsg_FlashClipboard_ReadDataReply(clipboard_string); + } + return result; +} + +int32_t PepperFlashClipboardMessageFilter::OnMsgWriteData( + ppapi::host::HostMessageContext* host_context, + uint32_t clipboard_type, + const std::vector<uint32_t>& formats, + const std::vector<std::string>& data) +{ + if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) { + NOTIMPLEMENTED(); + return PP_ERROR_FAILED; + } + if (formats.size() != data.size()) + return PP_ERROR_FAILED; + + ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); + ui::ClipboardType type = ConvertClipboardType(clipboard_type); + // If no formats are passed in clear the clipboard. + if (formats.size() == 0) { + clipboard->Clear(type); + return PP_OK; + } + + ui::ScopedClipboardWriter scw(type); + std::map<base::string16, std::string> custom_data_map; + int32_t res = PP_OK; + for (uint32_t i = 0; i < formats.size(); ++i) { + if (data[i].length() > kMaxClipboardWriteSize) { + res = PP_ERROR_NOSPACE; + break; + } + + switch (formats[i]) { + case PP_FLASH_CLIPBOARD_FORMAT_PLAINTEXT: + scw.WriteText(base::UTF8ToUTF16(data[i])); + break; + case PP_FLASH_CLIPBOARD_FORMAT_HTML: + scw.WriteHTML(base::UTF8ToUTF16(data[i]), std::string()); + break; + case PP_FLASH_CLIPBOARD_FORMAT_RTF: + scw.WriteRTF(data[i]); + break; + case PP_FLASH_CLIPBOARD_FORMAT_INVALID: + res = PP_ERROR_BADARGUMENT; + break; + default: + if (m_custom_formats.IsFormatRegistered(formats[i])) { + std::string format_name = m_custom_formats.GetFormatName(formats[i]); + custom_data_map[base::UTF8ToUTF16(format_name)] = data[i]; + } else { + // Invalid format. + res = PP_ERROR_BADARGUMENT; + break; + } + } + + if (res != PP_OK) + break; + } + + if (custom_data_map.size() > 0) { + base::Pickle pickle; + if (WriteDataToPickle(custom_data_map, &pickle)) { + scw.WritePickledData(pickle, ui::Clipboard::GetPepperCustomDataFormatType()); + } else { + res = PP_ERROR_BADARGUMENT; + } + } + + if (res != PP_OK) { + // Need to clear the objects so nothing is written. + scw.Reset(); + } + + return res; +} + +int32_t PepperFlashClipboardMessageFilter::OnMsgGetSequenceNumber( + ppapi::host::HostMessageContext* host_context, + uint32_t clipboard_type) +{ + if (clipboard_type != PP_FLASH_CLIPBOARD_TYPE_STANDARD) { + NOTIMPLEMENTED(); + return PP_ERROR_FAILED; + } + + ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread(); + ui::ClipboardType type = ConvertClipboardType(clipboard_type); + int64_t sequence_number = clipboard->GetSequenceNumber(type); + host_context->reply_msg = PpapiPluginMsg_FlashClipboard_GetSequenceNumberReply(sequence_number); + return PP_OK; +} + +} // namespace QtWebEngineCore diff --git a/src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.h b/src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.h new file mode 100644 index 000000000..c00e668ea --- /dev/null +++ b/src/core/renderer/pepper/pepper_flash_clipboard_message_filter_qt.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// based on chrome/browser/renderer_host/pepper/pepper_flash_clipboard_message_filter.h +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PEPPER_FLASH_CLIPBOARD_MESSAGE_FILTER_QT_H +#define PEPPER_FLASH_CLIPBOARD_MESSAGE_FILTER_QT_H + +#include <string> +#include <vector> + +#include "base/compiler_specific.h" +#include "ppapi/host/resource_message_filter.h" +#include "ppapi/shared_impl/flash_clipboard_format_registry.h" + +namespace ppapi { +namespace host { +struct HostMessageContext; +} +} + +namespace ui { +class ScopedClipboardWriter; +} + +namespace QtWebEngineCore { + +// Resource message filter for accessing the clipboard in Pepper. Pepper +// supports reading/writing custom formats from the clipboard. Currently, all +// custom formats that are read/written from the clipboard through pepper are +// stored in a single real clipboard format (in the same way the "web custom" +// clipboard formats are). This is done so that we don't have to have use real +// clipboard types for each custom clipboard format which may be a limited +// resource on a particular platform. +class PepperFlashClipboardMessageFilter : public ppapi::host::ResourceMessageFilter { +public: + PepperFlashClipboardMessageFilter(); + +protected: + // ppapi::host::ResourceMessageFilter overrides. + scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage(const IPC::Message& msg) override; + int32_t OnResourceMessageReceived(const IPC::Message& msg, ppapi::host::HostMessageContext* context) override; + +private: + ~PepperFlashClipboardMessageFilter() override; + + int32_t OnMsgRegisterCustomFormat(ppapi::host::HostMessageContext* host_context, const std::string& format_name); + int32_t OnMsgIsFormatAvailable(ppapi::host::HostMessageContext* host_context, + uint32_t clipboard_type, + uint32_t format); + int32_t OnMsgReadData(ppapi::host::HostMessageContext* host_context, + uint32_t clipoard_type, + uint32_t format); + int32_t OnMsgWriteData(ppapi::host::HostMessageContext* host_context, + uint32_t clipboard_type, + const std::vector<uint32_t>& formats, + const std::vector<std::string>& data); + int32_t OnMsgGetSequenceNumber(ppapi::host::HostMessageContext* host_context, + uint32_t clipboard_type); + + int32_t WriteClipboardDataItem(uint32_t format, + const std::string& data, + ui::ScopedClipboardWriter* scw); + + ppapi::FlashClipboardFormatRegistry m_custom_formats; + + DISALLOW_COPY_AND_ASSIGN(PepperFlashClipboardMessageFilter); +}; + +} // namespace QtWebEngineCore + +#endif // PEPPER_FLASH_CLIPBOARD_MESSAGE_FILTER_QT_H diff --git a/src/core/renderer/pepper/pepper_host_factory_qt.cpp b/src/core/renderer/pepper/pepper_host_factory_qt.cpp index 9fbd413ef..9b7236d8a 100644 --- a/src/core/renderer/pepper/pepper_host_factory_qt.cpp +++ b/src/core/renderer/pepper/pepper_host_factory_qt.cpp @@ -53,10 +53,10 @@ #include "ppapi/shared_impl/ppapi_permissions.h" #include "pepper_flash_browser_host_qt.h" +#include "pepper_flash_clipboard_message_filter_qt.h" #include "pepper_isolated_file_system_message_filter.h" using ppapi::host::MessageFilterHost; -using ppapi::host::ResourceHost; using ppapi::host::ResourceMessageFilter; namespace QtWebEngineCore { @@ -79,12 +79,18 @@ scoped_ptr<ppapi::host::ResourceHost> PepperHostFactoryQt::CreateResourceHost(pp if (!host_->IsValidInstance(instance)) return scoped_ptr<ppapi::host::ResourceHost>(); - if (host_->GetPpapiHost()->permissions().HasPermission(ppapi::PERMISSION_FLASH) - && message.type() == PpapiHostMsg_Flash_Create::ID) - return scoped_ptr<ppapi::host::ResourceHost>( - new PepperFlashBrowserHostQt(host_, - instance, - resource)); + // Flash interfaces. + if (host_->GetPpapiHost()->permissions().HasPermission(ppapi::PERMISSION_FLASH)) { + switch (message.type()) { + case PpapiHostMsg_Flash_Create::ID: + return scoped_ptr<ppapi::host::ResourceHost>(new PepperFlashBrowserHostQt(host_, instance, resource)); + case PpapiHostMsg_FlashClipboard_Create::ID: { + scoped_refptr<ResourceMessageFilter> clipboard_filter(new PepperFlashClipboardMessageFilter); + return scoped_ptr<ppapi::host::ResourceHost>(new MessageFilterHost( + host_->GetPpapiHost(), instance, resource, clipboard_filter)); + } + } + } // Permissions for the following interfaces will be checked at the // time of the corresponding instance's methods calls (because @@ -95,8 +101,8 @@ scoped_ptr<ppapi::host::ResourceHost> PepperHostFactoryQt::CreateResourceHost(pp if (message.type() == PpapiHostMsg_IsolatedFileSystem_Create::ID) { PepperIsolatedFileSystemMessageFilter* isolated_fs_filter = PepperIsolatedFileSystemMessageFilter::Create(instance, host_); if (!isolated_fs_filter) - return scoped_ptr<ResourceHost>(); - return scoped_ptr<ResourceHost>(new MessageFilterHost(host, instance, resource, isolated_fs_filter)); + return scoped_ptr<ppapi::host::ResourceHost>(); + return scoped_ptr<ppapi::host::ResourceHost>(new MessageFilterHost(host, instance, resource, isolated_fs_filter)); } return scoped_ptr<ppapi::host::ResourceHost>(); diff --git a/src/webengine/doc/src/qtwebengine-features.qdoc b/src/webengine/doc/src/qtwebengine-features.qdoc index f55eab23b..52f7da928 100644 --- a/src/webengine/doc/src/qtwebengine-features.qdoc +++ b/src/webengine/doc/src/qtwebengine-features.qdoc @@ -138,6 +138,8 @@ the user. Note that on Windows an external GPS receiver must be connected to the application. For more information, see \l{Qt Positioning}. + Support for this feature was added in Qt 5.5.0. + \section1 Pepper Plugin API Qt WebEngine supports loading Pepper Plugin API (PPAPI) plugins if diff --git a/src/webengine/doc/src/qtwebengine-overview.qdoc b/src/webengine/doc/src/qtwebengine-overview.qdoc index d4d9af199..7ae3afaf4 100644 --- a/src/webengine/doc/src/qtwebengine-overview.qdoc +++ b/src/webengine/doc/src/qtwebengine-overview.qdoc @@ -60,16 +60,16 @@ The functionality in Qt WebEngine is divided into the following modules: \list - \li \l{Qt WebEngine Widgets} for creating widget-based web applications - \li \l{Qt WebEngine} for creating Qt Quick based web applications - \li \l{Qt WebEngine Core} for interacting with Chromium + \li \l{Qt WebEngine Widgets Module} for creating widget-based web applications + \li \l{Qt WebEngine Module} for creating Qt Quick based web applications + \li \l{Qt WebEngine Core Module} for interacting with Chromium \endlist Page rendering and JavaScript execution are separated from the GUI process into the Qt WebEngine Process. It is a library that must be shipped with the application if the Qt libraries are bundled into the application. - \section2 Qt WebEngine Widgets + \section2 Qt WebEngine Widgets Module \image qtwebenginewidgets-model.png @@ -82,7 +82,7 @@ \e cookies. Profiles can be used to isolate pages from each other. A typical use case is a dedicated profile for a \e {private browsing} mode, where no information is permanently saved. - \section2 Qt WebEngine + \section2 Qt WebEngine Module \image qtwebengine-model.png @@ -90,7 +90,7 @@ except that there is no separately accessible web engine page. The supported page functionality is integrated into the web engine view. - \section2 Qt WebEngine Core + \section2 Qt WebEngine Core Module The Qt WebEngine core is based on the \l {Chromium Project}. Chromium provides its own network and painting engines and is developed tightly together with its dependent modules, and diff --git a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc index f3faac3c1..ecec53bda 100644 --- a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc +++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc @@ -87,6 +87,7 @@ \section2 Linux On Linux, Clang or GCC version 4.7 or later is required. + Supported configurations are \c linux-g++ and \c{linux-clang}. Qt WebEngine requires \c pkg-config to detect most of its dependencies. The following \c pkg-config files are required: diff --git a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc index c2f810b2a..558aa1f50 100644 --- a/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebenginesettings_lgpl.qdoc @@ -88,7 +88,8 @@ This enum type specifies settings for web pages: \value AutoLoadImages - Automatically loads images on web pages. Enabled by default. + Automatically dowloads images for web pages. When this setting is + disabled, images are loaded from the cache. Enabled by default. \value JavascriptEnabled Enables the running of JavaScript programs. Enabled by default. \value JavascriptCanOpenWindows |