/* * Copyright (C) 2010 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "PluginProxy.h" #if ENABLE(NETSCAPE_PLUGIN_API) #include "DataReference.h" #include "NPRemoteObjectMap.h" #include "NPRuntimeUtilities.h" #include "NPVariantData.h" #include "PluginController.h" #include "PluginControllerProxyMessages.h" #include "PluginCreationParameters.h" #include "PluginProcessConnection.h" #include "PluginProcessConnectionManager.h" #include "ShareableBitmap.h" #include "WebCoreArgumentCoders.h" #include "WebEvent.h" #include "WebProcess.h" #include "WebProcessConnectionMessages.h" #include #include using namespace WebCore; namespace WebKit { static uint64_t generatePluginInstanceID() { static uint64_t uniquePluginInstanceID; return ++uniquePluginInstanceID; } Ref PluginProxy::create(uint64_t pluginProcessToken, bool isRestartedProcess) { return adoptRef(*new PluginProxy(pluginProcessToken, isRestartedProcess)); } PluginProxy::PluginProxy(uint64_t pluginProcessToken, bool isRestartedProcess) : Plugin(PluginProxyType) , m_pluginProcessToken(pluginProcessToken) , m_pluginInstanceID(generatePluginInstanceID()) , m_pluginBackingStoreContainsValidData(false) , m_isStarted(false) , m_waitingForPaintInResponseToUpdate(false) , m_wantsWheelEvents(false) , m_remoteLayerClientID(0) , m_waitingOnAsynchronousInitialization(false) , m_isRestartedProcess(isRestartedProcess) { } PluginProxy::~PluginProxy() { } void PluginProxy::pluginProcessCrashed() { controller()->pluginProcessCrashed(); } bool PluginProxy::initialize(const Parameters& parameters) { ASSERT(!m_connection); m_connection = WebProcess::singleton().pluginProcessConnectionManager().getPluginProcessConnection(m_pluginProcessToken); if (!m_connection) return false; // Add the plug-in proxy before creating the plug-in; it needs to be in the map because CreatePlugin // can call back out to the plug-in proxy. m_connection->addPluginProxy(this); // Ask the plug-in process to create a plug-in. m_pendingPluginCreationParameters = std::make_unique(); m_pendingPluginCreationParameters->pluginInstanceID = m_pluginInstanceID; m_pendingPluginCreationParameters->windowNPObjectID = windowNPObjectID(); m_pendingPluginCreationParameters->parameters = parameters; m_pendingPluginCreationParameters->userAgent = controller()->userAgent(); m_pendingPluginCreationParameters->contentsScaleFactor = contentsScaleFactor(); m_pendingPluginCreationParameters->isPrivateBrowsingEnabled = controller()->isPrivateBrowsingEnabled(); m_pendingPluginCreationParameters->isMuted = controller()->isMuted(); m_pendingPluginCreationParameters->artificialPluginInitializationDelayEnabled = controller()->artificialPluginInitializationDelayEnabled(); m_pendingPluginCreationParameters->isAcceleratedCompositingEnabled = controller()->isAcceleratedCompositingEnabled(); if (!canInitializeAsynchronously()) return initializeSynchronously(); // Remember that we tried to create this plug-in asynchronously in case we need to create it synchronously later. m_waitingOnAsynchronousInitialization = true; PluginCreationParameters creationParameters(*m_pendingPluginCreationParameters.get()); m_connection->connection()->send(Messages::WebProcessConnection::CreatePluginAsynchronously(creationParameters), m_pluginInstanceID); return true; } bool PluginProxy::canInitializeAsynchronously() const { return controller()->asynchronousPluginInitializationEnabled() && (m_connection->supportsAsynchronousPluginInitialization() || controller()->asynchronousPluginInitializationEnabledForAllPlugins()); } bool PluginProxy::initializeSynchronously() { ASSERT(m_pendingPluginCreationParameters); m_pendingPluginCreationParameters->asynchronousCreationIncomplete = m_waitingOnAsynchronousInitialization; bool result = false; bool wantsWheelEvents = false; uint32_t remoteLayerClientID = 0; PluginCreationParameters parameters(*m_pendingPluginCreationParameters.get()); if (!m_connection->connection()->sendSync(Messages::WebProcessConnection::CreatePlugin(parameters), Messages::WebProcessConnection::CreatePlugin::Reply(result, wantsWheelEvents, remoteLayerClientID), 0) || !result) didFailToCreatePluginInternal(); else didCreatePluginInternal(wantsWheelEvents, remoteLayerClientID); return result; } void PluginProxy::didCreatePlugin(bool wantsWheelEvents, uint32_t remoteLayerClientID) { // We might have tried to create the plug-in sychronously while waiting on the asynchronous reply, // in which case we should ignore this message. if (!m_waitingOnAsynchronousInitialization) return; didCreatePluginInternal(wantsWheelEvents, remoteLayerClientID); } void PluginProxy::didFailToCreatePlugin() { // We might have tried to create the plug-in sychronously while waiting on the asynchronous reply, // in which case we should ignore this message. if (!m_waitingOnAsynchronousInitialization) return; didFailToCreatePluginInternal(); } void PluginProxy::didCreatePluginInternal(bool wantsWheelEvents, uint32_t remoteLayerClientID) { m_wantsWheelEvents = wantsWheelEvents; m_remoteLayerClientID = remoteLayerClientID; m_isStarted = true; controller()->didInitializePlugin(); // Whether synchronously or asynchronously, this plug-in was created and we shouldn't need to remember // anything about how. m_pendingPluginCreationParameters = nullptr; m_waitingOnAsynchronousInitialization = false; } void PluginProxy::didFailToCreatePluginInternal() { // Calling out to the connection and the controller could potentially cause the plug-in proxy to go away, so protect it here. Ref protect(*this); m_connection->removePluginProxy(this); controller()->didFailToInitializePlugin(); // Whether synchronously or asynchronously, this plug-in failed to create and we shouldn't need to remember // anything about how. m_pendingPluginCreationParameters = nullptr; m_waitingOnAsynchronousInitialization = false; } void PluginProxy::destroy() { m_isStarted = false; if (!m_connection) return; m_connection->connection()->sendSync(Messages::WebProcessConnection::DestroyPlugin(m_pluginInstanceID, m_waitingOnAsynchronousInitialization), Messages::WebProcessConnection::DestroyPlugin::Reply(), 0); m_connection->removePluginProxy(this); } void PluginProxy::paint(GraphicsContext& graphicsContext, const IntRect& dirtyRect) { if (!needsBackingStore() || !m_backingStore) return; if (!m_pluginBackingStoreContainsValidData) { m_connection->connection()->sendSync(Messages::PluginControllerProxy::PaintEntirePlugin(), Messages::PluginControllerProxy::PaintEntirePlugin::Reply(), m_pluginInstanceID); // Blit the plug-in backing store into our own backing store. auto graphicsContext = m_backingStore->createGraphicsContext(); graphicsContext->applyDeviceScaleFactor(contentsScaleFactor()); graphicsContext->setCompositeOperation(CompositeCopy); m_pluginBackingStore->paint(*graphicsContext, contentsScaleFactor(), IntPoint(), pluginBounds()); m_pluginBackingStoreContainsValidData = true; } m_backingStore->paint(graphicsContext, contentsScaleFactor(), dirtyRect.location(), dirtyRect); if (m_waitingForPaintInResponseToUpdate) { m_waitingForPaintInResponseToUpdate = false; m_connection->connection()->send(Messages::PluginControllerProxy::DidUpdate(), m_pluginInstanceID); } } bool PluginProxy::supportsSnapshotting() const { if (m_waitingOnAsynchronousInitialization) return false; bool isSupported = false; if (m_connection && !m_connection->connection()->sendSync(Messages::PluginControllerProxy::SupportsSnapshotting(), Messages::PluginControllerProxy::SupportsSnapshotting::Reply(isSupported), m_pluginInstanceID)) return false; return isSupported; } RefPtr PluginProxy::snapshot() { ShareableBitmap::Handle snapshotStoreHandle; m_connection->connection()->sendSync(Messages::PluginControllerProxy::Snapshot(), Messages::PluginControllerProxy::Snapshot::Reply(snapshotStoreHandle), m_pluginInstanceID); if (snapshotStoreHandle.isNull()) return nullptr; RefPtr snapshotBuffer = ShareableBitmap::create(snapshotStoreHandle); return snapshotBuffer; } bool PluginProxy::isTransparent() { // This should never be called from the web process. ASSERT_NOT_REACHED(); return false; } bool PluginProxy::wantsWheelEvents() { return m_wantsWheelEvents; } void PluginProxy::geometryDidChange() { ASSERT(m_isStarted); ShareableBitmap::Handle pluginBackingStoreHandle; if (updateBackingStore()) { // Create a new plug-in backing store. m_pluginBackingStore = ShareableBitmap::createShareable(m_backingStore->size(), ShareableBitmap::SupportsAlpha); if (!m_pluginBackingStore) return; // Create a handle to the plug-in backing store so we can send it over. if (!m_pluginBackingStore->createHandle(pluginBackingStoreHandle)) { m_pluginBackingStore = nullptr; return; } m_pluginBackingStoreContainsValidData = false; } m_connection->connection()->send(Messages::PluginControllerProxy::GeometryDidChange(m_pluginSize, m_clipRect, m_pluginToRootViewTransform, contentsScaleFactor(), pluginBackingStoreHandle), m_pluginInstanceID, IPC::DispatchMessageEvenWhenWaitingForSyncReply); } void PluginProxy::geometryDidChange(const IntSize& pluginSize, const IntRect& clipRect, const AffineTransform& pluginToRootViewTransform) { if (pluginSize == m_pluginSize && m_clipRect == clipRect && m_pluginToRootViewTransform == pluginToRootViewTransform) { // Nothing to do. return; } m_pluginSize = pluginSize; m_clipRect = clipRect; m_pluginToRootViewTransform = pluginToRootViewTransform; geometryDidChange(); } void PluginProxy::visibilityDidChange(bool isVisible) { ASSERT(m_isStarted); m_connection->connection()->send(Messages::PluginControllerProxy::VisibilityDidChange(isVisible), m_pluginInstanceID); } void PluginProxy::frameDidFinishLoading(uint64_t requestID) { m_connection->connection()->send(Messages::PluginControllerProxy::FrameDidFinishLoading(requestID), m_pluginInstanceID); } void PluginProxy::frameDidFail(uint64_t requestID, bool wasCancelled) { m_connection->connection()->send(Messages::PluginControllerProxy::FrameDidFail(requestID, wasCancelled), m_pluginInstanceID); } void PluginProxy::didEvaluateJavaScript(uint64_t requestID, const WTF::String& result) { m_connection->connection()->send(Messages::PluginControllerProxy::DidEvaluateJavaScript(requestID, result), m_pluginInstanceID); } void PluginProxy::streamWillSendRequest(uint64_t streamID, const URL& requestURL, const URL& responseURL, int responseStatus) { m_connection->connection()->send(Messages::PluginControllerProxy::StreamWillSendRequest(streamID, requestURL.string(), responseURL.string(), responseStatus), m_pluginInstanceID); } void PluginProxy::streamDidReceiveResponse(uint64_t streamID, const URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const WTF::String& mimeType, const WTF::String& headers, const String& /* suggestedFileName */) { m_connection->connection()->send(Messages::PluginControllerProxy::StreamDidReceiveResponse(streamID, responseURL.string(), streamLength, lastModifiedTime, mimeType, headers), m_pluginInstanceID); } void PluginProxy::streamDidReceiveData(uint64_t streamID, const char* bytes, int length) { m_connection->connection()->send(Messages::PluginControllerProxy::StreamDidReceiveData(streamID, IPC::DataReference(reinterpret_cast(bytes), length)), m_pluginInstanceID); } void PluginProxy::streamDidFinishLoading(uint64_t streamID) { m_connection->connection()->send(Messages::PluginControllerProxy::StreamDidFinishLoading(streamID), m_pluginInstanceID); } void PluginProxy::streamDidFail(uint64_t streamID, bool wasCancelled) { m_connection->connection()->send(Messages::PluginControllerProxy::StreamDidFail(streamID, wasCancelled), m_pluginInstanceID); } void PluginProxy::manualStreamDidReceiveResponse(const URL& responseURL, uint32_t streamLength, uint32_t lastModifiedTime, const WTF::String& mimeType, const WTF::String& headers, const String& /* suggestedFileName */) { m_connection->connection()->send(Messages::PluginControllerProxy::ManualStreamDidReceiveResponse(responseURL.string(), streamLength, lastModifiedTime, mimeType, headers), m_pluginInstanceID); } void PluginProxy::manualStreamDidReceiveData(const char* bytes, int length) { m_connection->connection()->send(Messages::PluginControllerProxy::ManualStreamDidReceiveData(IPC::DataReference(reinterpret_cast(bytes), length)), m_pluginInstanceID); } void PluginProxy::manualStreamDidFinishLoading() { m_connection->connection()->send(Messages::PluginControllerProxy::ManualStreamDidFinishLoading(), m_pluginInstanceID); } void PluginProxy::manualStreamDidFail(bool wasCancelled) { m_connection->connection()->send(Messages::PluginControllerProxy::ManualStreamDidFail(wasCancelled), m_pluginInstanceID); } bool PluginProxy::handleMouseEvent(const WebMouseEvent& mouseEvent) { if (m_waitingOnAsynchronousInitialization) return false; m_connection->connection()->send(Messages::PluginControllerProxy::HandleMouseEvent(mouseEvent), m_pluginInstanceID); return true; } bool PluginProxy::handleWheelEvent(const WebWheelEvent& wheelEvent) { if (m_waitingOnAsynchronousInitialization) return false; bool handled = false; if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::HandleWheelEvent(wheelEvent), Messages::PluginControllerProxy::HandleWheelEvent::Reply(handled), m_pluginInstanceID)) return false; return handled; } bool PluginProxy::handleMouseEnterEvent(const WebMouseEvent& mouseEnterEvent) { if (m_waitingOnAsynchronousInitialization) return false; bool handled = false; if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::HandleMouseEnterEvent(mouseEnterEvent), Messages::PluginControllerProxy::HandleMouseEnterEvent::Reply(handled), m_pluginInstanceID)) return false; return handled; } bool PluginProxy::handleMouseLeaveEvent(const WebMouseEvent& mouseLeaveEvent) { if (m_waitingOnAsynchronousInitialization) return false; bool handled = false; if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::HandleMouseLeaveEvent(mouseLeaveEvent), Messages::PluginControllerProxy::HandleMouseLeaveEvent::Reply(handled), m_pluginInstanceID)) return false; return handled; } bool PluginProxy::handleContextMenuEvent(const WebMouseEvent&) { // We don't know if the plug-in has handled mousedown event by displaying a context menu, so we never want WebKit to show a default one. return true; } bool PluginProxy::handleKeyboardEvent(const WebKeyboardEvent& keyboardEvent) { if (m_waitingOnAsynchronousInitialization) return false; bool handled = false; if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::HandleKeyboardEvent(keyboardEvent), Messages::PluginControllerProxy::HandleKeyboardEvent::Reply(handled), m_pluginInstanceID)) return false; return handled; } void PluginProxy::setFocus(bool hasFocus) { m_connection->connection()->send(Messages::PluginControllerProxy::SetFocus(hasFocus), m_pluginInstanceID); } bool PluginProxy::handleEditingCommand(const String& commandName, const String& argument) { if (m_waitingOnAsynchronousInitialization) return false; bool handled = false; if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::HandleEditingCommand(commandName, argument), Messages::PluginControllerProxy::HandleEditingCommand::Reply(handled), m_pluginInstanceID)) return false; return handled; } bool PluginProxy::isEditingCommandEnabled(const String& commandName) { if (m_waitingOnAsynchronousInitialization) return false; bool enabled = false; if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::IsEditingCommandEnabled(commandName), Messages::PluginControllerProxy::IsEditingCommandEnabled::Reply(enabled), m_pluginInstanceID)) return false; return enabled; } bool PluginProxy::handlesPageScaleFactor() const { if (m_waitingOnAsynchronousInitialization) return false; bool handled = false; if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::HandlesPageScaleFactor(), Messages::PluginControllerProxy::HandlesPageScaleFactor::Reply(handled), m_pluginInstanceID)) return false; return handled; } bool PluginProxy::requiresUnifiedScaleFactor() const { if (m_waitingOnAsynchronousInitialization) return false; bool required = false; if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::RequiresUnifiedScaleFactor(), Messages::PluginControllerProxy::RequiresUnifiedScaleFactor::Reply(required), m_pluginInstanceID)) return false; return required; } NPObject* PluginProxy::pluginScriptableNPObject() { // Sending the synchronous Messages::PluginControllerProxy::GetPluginScriptableNPObject message can cause us to dispatch an // incoming synchronous message that ends up destroying the PluginProxy object. PluginController::PluginDestructionProtector protector(controller()); uint64_t pluginScriptableNPObjectID = 0; if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::GetPluginScriptableNPObject(), Messages::PluginControllerProxy::GetPluginScriptableNPObject::Reply(pluginScriptableNPObjectID), m_pluginInstanceID)) return 0; if (!pluginScriptableNPObjectID) return 0; return m_connection->npRemoteObjectMap()->createNPObjectProxy(pluginScriptableNPObjectID, this); } void PluginProxy::windowFocusChanged(bool hasFocus) { m_connection->connection()->send(Messages::PluginControllerProxy::WindowFocusChanged(hasFocus), m_pluginInstanceID); } void PluginProxy::windowVisibilityChanged(bool isVisible) { m_connection->connection()->send(Messages::PluginControllerProxy::WindowVisibilityChanged(isVisible), m_pluginInstanceID); } #if PLATFORM(COCOA) void PluginProxy::windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates) { m_connection->connection()->send(Messages::PluginControllerProxy::WindowAndViewFramesChanged(windowFrameInScreenCoordinates, viewFrameInWindowCoordinates), m_pluginInstanceID); } uint64_t PluginProxy::pluginComplexTextInputIdentifier() const { return m_pluginInstanceID; } void PluginProxy::sendComplexTextInput(const String& textInput) { m_connection->connection()->send(Messages::PluginControllerProxy::SendComplexTextInput(textInput), m_pluginInstanceID); } #endif void PluginProxy::contentsScaleFactorChanged(float) { geometryDidChange(); } void PluginProxy::storageBlockingStateChanged(bool isStorageBlockingEnabled) { m_connection->connection()->send(Messages::PluginControllerProxy::StorageBlockingStateChanged(isStorageBlockingEnabled), m_pluginInstanceID); } void PluginProxy::privateBrowsingStateChanged(bool isPrivateBrowsingEnabled) { m_connection->connection()->send(Messages::PluginControllerProxy::PrivateBrowsingStateChanged(isPrivateBrowsingEnabled), m_pluginInstanceID); } void PluginProxy::mutedStateChanged(bool isMuted) { m_connection->connection()->send(Messages::PluginControllerProxy::MutedStateChanged(isMuted), m_pluginInstanceID); } bool PluginProxy::getFormValue(String& formValue) { bool returnValue; if (!m_connection->connection()->sendSync(Messages::PluginControllerProxy::GetFormValue(), Messages::PluginControllerProxy::GetFormValue::Reply(returnValue, formValue), m_pluginInstanceID)) return false; return returnValue; } bool PluginProxy::handleScroll(ScrollDirection, ScrollGranularity) { return false; } Scrollbar* PluginProxy::horizontalScrollbar() { return 0; } Scrollbar* PluginProxy::verticalScrollbar() { return 0; } void PluginProxy::loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, const HTTPHeaderMap& headerFields, const Vector& httpBody, bool allowPopups) { controller()->loadURL(requestID, method, urlString, target, headerFields, httpBody, allowPopups); } void PluginProxy::proxiesForURL(const String& urlString, String& proxyString) { proxyString = controller()->proxiesForURL(urlString); } void PluginProxy::cookiesForURL(const String& urlString, String& cookieString) { cookieString = controller()->cookiesForURL(urlString); } void PluginProxy::setCookiesForURL(const String& urlString, const String& cookieString) { controller()->setCookiesForURL(urlString, cookieString); } void PluginProxy::getAuthenticationInfo(const ProtectionSpace& protectionSpace, bool& returnValue, String& username, String& password) { returnValue = controller()->getAuthenticationInfo(protectionSpace, username, password); } float PluginProxy::contentsScaleFactor() { return controller()->contentsScaleFactor(); } bool PluginProxy::updateBackingStore() { if (m_pluginSize.isEmpty() || !needsBackingStore()) return false; IntSize backingStoreSize = m_pluginSize; backingStoreSize.scale(contentsScaleFactor()); if (m_backingStore) { if (m_backingStore->size() == backingStoreSize) return false; m_backingStore = nullptr; // Give malloc a chance to recycle our backing store. } m_backingStore = ShareableBitmap::create(backingStoreSize, ShareableBitmap::SupportsAlpha); return !!m_backingStore; } uint64_t PluginProxy::windowNPObjectID() { NPObject* windowScriptNPObject = controller()->windowScriptNPObject(); if (!windowScriptNPObject) return 0; uint64_t windowNPObjectID = m_connection->npRemoteObjectMap()->registerNPObject(windowScriptNPObject, this); releaseNPObject(windowScriptNPObject); return windowNPObjectID; } IntRect PluginProxy::pluginBounds() { return IntRect(IntPoint(), m_pluginSize); } void PluginProxy::getPluginElementNPObject(uint64_t& pluginElementNPObjectID) { NPObject* pluginElementNPObject = controller()->pluginElementNPObject(); if (!pluginElementNPObject) { pluginElementNPObjectID = 0; return; } pluginElementNPObjectID = m_connection->npRemoteObjectMap()->registerNPObject(pluginElementNPObject, this); releaseNPObject(pluginElementNPObject); } void PluginProxy::evaluate(const NPVariantData& npObjectAsVariantData, const String& scriptString, bool allowPopups, bool& returnValue, NPVariantData& resultData) { PluginController::PluginDestructionProtector protector(controller()); NPVariant npObjectAsVariant = m_connection->npRemoteObjectMap()->npVariantDataToNPVariant(npObjectAsVariantData, this); if (!NPVARIANT_IS_OBJECT(npObjectAsVariant) || !(NPVARIANT_TO_OBJECT(npObjectAsVariant))) { returnValue = false; return; } NPVariant result; returnValue = controller()->evaluate(NPVARIANT_TO_OBJECT(npObjectAsVariant), scriptString, &result, allowPopups); if (!returnValue) return; // Convert the NPVariant to an NPVariantData. resultData = m_connection->npRemoteObjectMap()->npVariantToNPVariantData(result, this); // And release the result. releaseNPVariantValue(&result); releaseNPVariantValue(&npObjectAsVariant); } void PluginProxy::setPluginIsPlayingAudio(bool pluginIsPlayingAudio) { controller()->setPluginIsPlayingAudio(pluginIsPlayingAudio); } void PluginProxy::continueStreamLoad(uint64_t streamID) { controller()->continueStreamLoad(streamID); } void PluginProxy::cancelStreamLoad(uint64_t streamID) { controller()->cancelStreamLoad(streamID); } void PluginProxy::cancelManualStreamLoad() { controller()->cancelManualStreamLoad(); } void PluginProxy::setStatusbarText(const String& statusbarText) { controller()->setStatusbarText(statusbarText); } #if PLUGIN_ARCHITECTURE(X11) void PluginProxy::createPluginContainer(uint64_t& windowID) { windowID = controller()->createPluginContainer(); } void PluginProxy::windowedPluginGeometryDidChange(const WebCore::IntRect& frameRect, const WebCore::IntRect& clipRect, uint64_t windowID) { controller()->windowedPluginGeometryDidChange(frameRect, clipRect, windowID); } void PluginProxy::windowedPluginVisibilityDidChange(bool isVisible, uint64_t windowID) { controller()->windowedPluginVisibilityDidChange(isVisible, windowID); } #endif void PluginProxy::update(const IntRect& paintedRect) { if (paintedRect == pluginBounds()) m_pluginBackingStoreContainsValidData = true; if (m_backingStore) { // Blit the plug-in backing store into our own backing store. auto graphicsContext = m_backingStore->createGraphicsContext(); graphicsContext->applyDeviceScaleFactor(contentsScaleFactor()); graphicsContext->setCompositeOperation(CompositeCopy); m_pluginBackingStore->paint(*graphicsContext, contentsScaleFactor(), paintedRect.location(), paintedRect); } // Ask the controller to invalidate the rect for us. m_waitingForPaintInResponseToUpdate = true; controller()->invalidate(paintedRect); } IntPoint PluginProxy::convertToRootView(const IntPoint& point) const { return m_pluginToRootViewTransform.mapPoint(point); } RefPtr PluginProxy::liveResourceData() const { return nullptr; } #if PLATFORM(COCOA) WebCore::AudioHardwareActivityType PluginProxy::audioHardwareActivity() const { return m_connection->audioHardwareActivity(); } #endif } // namespace WebKit #endif // ENABLE(NETSCAPE_PLUGIN_API)