1/*
2 * Copyright (C) 2010 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "PluginControllerProxy.h"
28
29#if ENABLE(NETSCAPE_PLUGIN_API)
30
31#include "DataReference.h"
32#include "NPObjectProxy.h"
33#include "NPRemoteObjectMap.h"
34#include "NPRuntimeUtilities.h"
35#include "NPVariantData.h"
36#include "NetscapePlugin.h"
37#include "PluginCreationParameters.h"
38#include "PluginProcess.h"
39#include "PluginProxyMessages.h"
40#include "ShareableBitmap.h"
41#include "WebCoreArgumentCoders.h"
42#include "WebProcessConnection.h"
43#include <WebCore/GraphicsContext.h>
44#include <WebCore/HTTPHeaderMap.h>
45#include <WebCore/IdentifierRep.h>
46#include <WebCore/NotImplemented.h>
47#include <wtf/SetForScope.h>
48#include <wtf/text/WTFString.h>
49
50#if PLATFORM(COCOA)
51#include "LayerHostingContext.h"
52#endif
53
54namespace WebKit {
55using namespace WebCore;
56
57PluginControllerProxy::PluginControllerProxy(WebProcessConnection* connection, const PluginCreationParameters& creationParameters)
58 : m_connection(connection)
59 , m_pluginInstanceID(creationParameters.pluginInstanceID)
60 , m_userAgent(creationParameters.userAgent)
61 , m_isPrivateBrowsingEnabled(creationParameters.isPrivateBrowsingEnabled)
62 , m_isMuted(creationParameters.isMuted)
63 , m_isAcceleratedCompositingEnabled(creationParameters.isAcceleratedCompositingEnabled)
64 , m_isInitializing(false)
65 , m_isVisible(false)
66 , m_isWindowVisible(false)
67 , m_paintTimer(RunLoop::main(), this, &PluginControllerProxy::paint)
68 , m_pluginDestructionProtectCount(0)
69 , m_pluginDestroyTimer(RunLoop::main(), this, &PluginControllerProxy::destroy)
70 , m_waitingForDidUpdate(false)
71 , m_pluginCanceledManualStreamLoad(false)
72#if PLATFORM(COCOA)
73 , m_isComplexTextInputEnabled(false)
74#endif
75 , m_contentsScaleFactor(creationParameters.contentsScaleFactor)
76 , m_windowNPObject(0)
77 , m_pluginElementNPObject(0)
78 , m_visiblityActivity("Plugin is visible.")
79{
80}
81
82PluginControllerProxy::~PluginControllerProxy()
83{
84 ASSERT(!m_plugin);
85
86 if (m_windowNPObject)
87 releaseNPObject(m_windowNPObject);
88
89 if (m_pluginElementNPObject)
90 releaseNPObject(m_pluginElementNPObject);
91}
92
93void PluginControllerProxy::setInitializationReply(Messages::WebProcessConnection::CreatePlugin::DelayedReply&& reply)
94{
95 ASSERT(!m_initializationReply);
96 m_initializationReply = WTFMove(reply);
97}
98
99Messages::WebProcessConnection::CreatePlugin::DelayedReply PluginControllerProxy::takeInitializationReply()
100{
101 return std::exchange(m_initializationReply, nullptr);
102}
103
104bool PluginControllerProxy::initialize(const PluginCreationParameters& creationParameters)
105{
106 ASSERT(!m_plugin);
107
108 ASSERT(!m_isInitializing);
109 m_isInitializing = true; // Cannot use SetForScope here, because this object can be deleted before the function returns.
110
111 m_plugin = NetscapePlugin::create(PluginProcess::singleton().netscapePluginModule());
112 if (!m_plugin) {
113 // This will delete the plug-in controller proxy object.
114 m_connection->removePluginControllerProxy(this, 0);
115 return false;
116 }
117
118 if (creationParameters.windowNPObjectID)
119 m_windowNPObject = m_connection->npRemoteObjectMap()->createNPObjectProxy(creationParameters.windowNPObjectID, m_plugin.get());
120
121 bool returnValue = m_plugin->initialize(this, creationParameters.parameters);
122
123 if (!returnValue) {
124 // Get the plug-in so we can pass it to removePluginControllerProxy. The pointer is only
125 // used as an identifier so it's OK to just get a weak reference.
126 Plugin* plugin = m_plugin.get();
127
128 m_plugin = nullptr;
129
130 // This will delete the plug-in controller proxy object.
131 m_connection->removePluginControllerProxy(this, plugin);
132 return false;
133 }
134
135 platformInitialize(creationParameters);
136
137 m_isInitializing = false;
138 return true;
139}
140
141void PluginControllerProxy::destroy()
142{
143 ASSERT(m_plugin);
144
145 // FIXME: Consider removing m_pluginDestructionProtectCount and always use inSendSync here.
146 if (m_pluginDestructionProtectCount || m_connection->connection()->inSendSync()) {
147 // We have plug-in code on the stack so we can't destroy it right now.
148 // Destroy it later.
149 m_pluginDestroyTimer.startOneShot(0_s);
150 return;
151 }
152
153 // Get the plug-in so we can pass it to removePluginControllerProxy. The pointer is only
154 // used as an identifier so it's OK to just get a weak reference.
155 Plugin* plugin = m_plugin.get();
156
157 m_plugin->destroyPlugin();
158 m_plugin = nullptr;
159
160 platformDestroy();
161
162 // This will delete the plug-in controller proxy object.
163 m_connection->removePluginControllerProxy(this, plugin);
164}
165
166bool PluginControllerProxy::wantsWheelEvents() const
167{
168 return m_plugin->wantsWheelEvents();
169}
170
171void PluginControllerProxy::paint()
172{
173 ASSERT(!m_dirtyRect.isEmpty());
174 m_paintTimer.stop();
175
176 if (!m_backingStore)
177 return;
178
179 IntRect dirtyRect = m_dirtyRect;
180 m_dirtyRect = IntRect();
181
182 ASSERT(m_plugin);
183
184 // Create a graphics context.
185 auto graphicsContext = m_backingStore->createGraphicsContext();
186
187#if PLATFORM(COCOA)
188 // FIXME: We should really call applyDeviceScaleFactor instead of scale, but that ends up calling into WKSI
189 // which we currently don't have initiated in the plug-in process.
190 graphicsContext->scale(m_contentsScaleFactor);
191#endif
192
193 if (m_plugin->isTransparent())
194 graphicsContext->clearRect(dirtyRect);
195
196 m_plugin->paint(*graphicsContext, dirtyRect);
197
198 m_connection->connection()->send(Messages::PluginProxy::Update(dirtyRect), m_pluginInstanceID);
199}
200
201void PluginControllerProxy::startPaintTimer()
202{
203 // Check if we should start the timer.
204
205 if (m_dirtyRect.isEmpty())
206 return;
207
208 // FIXME: Check clip rect.
209
210 if (m_paintTimer.isActive())
211 return;
212
213 if (m_waitingForDidUpdate)
214 return;
215
216 // Start the timer.
217 m_paintTimer.startOneShot(0_s);
218
219 m_waitingForDidUpdate = true;
220}
221
222void PluginControllerProxy::invalidate(const IntRect& rect)
223{
224 IntRect dirtyRect = rect;
225
226 // Make sure that the dirty rect is not greater than the plug-in itself.
227 dirtyRect.intersect(IntRect(IntPoint(), m_pluginSize));
228 m_dirtyRect.unite(dirtyRect);
229
230 startPaintTimer();
231}
232
233String PluginControllerProxy::userAgent()
234{
235 return m_userAgent;
236}
237
238void PluginControllerProxy::loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, const HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, bool allowPopups)
239{
240 m_connection->connection()->send(Messages::PluginProxy::LoadURL(requestID, method, urlString, target, headerFields, httpBody, allowPopups), m_pluginInstanceID);
241}
242
243void PluginControllerProxy::continueStreamLoad(uint64_t streamID)
244{
245 m_connection->connection()->send(Messages::PluginProxy::ContinueStreamLoad(streamID), m_pluginInstanceID);
246}
247
248void PluginControllerProxy::cancelStreamLoad(uint64_t streamID)
249{
250 m_connection->connection()->send(Messages::PluginProxy::CancelStreamLoad(streamID), m_pluginInstanceID);
251}
252
253void PluginControllerProxy::cancelManualStreamLoad()
254{
255 m_pluginCanceledManualStreamLoad = true;
256
257 m_connection->connection()->send(Messages::PluginProxy::CancelManualStreamLoad(), m_pluginInstanceID);
258}
259
260NPObject* PluginControllerProxy::windowScriptNPObject()
261{
262 if (!m_windowNPObject)
263 return 0;
264
265 retainNPObject(m_windowNPObject);
266 return m_windowNPObject;
267}
268
269NPObject* PluginControllerProxy::pluginElementNPObject()
270{
271 if (!m_pluginElementNPObject) {
272 uint64_t pluginElementNPObjectID = 0;
273
274 if (!m_connection->connection()->sendSync(Messages::PluginProxy::GetPluginElementNPObject(), Messages::PluginProxy::GetPluginElementNPObject::Reply(pluginElementNPObjectID), m_pluginInstanceID))
275 return 0;
276
277 if (!pluginElementNPObjectID)
278 return 0;
279
280 m_pluginElementNPObject = m_connection->npRemoteObjectMap()->createNPObjectProxy(pluginElementNPObjectID, m_plugin.get());
281 ASSERT(m_pluginElementNPObject);
282 }
283
284 retainNPObject(m_pluginElementNPObject);
285 return m_pluginElementNPObject;
286}
287
288bool PluginControllerProxy::evaluate(NPObject* npObject, const String& scriptString, NPVariant* result, bool allowPopups)
289{
290 PluginDestructionProtector protector(this);
291
292 NPVariant npObjectAsNPVariant;
293 OBJECT_TO_NPVARIANT(npObject, npObjectAsNPVariant);
294
295 // Send the NPObject over as an NPVariantData.
296 NPVariantData npObjectAsNPVariantData = m_connection->npRemoteObjectMap()->npVariantToNPVariantData(npObjectAsNPVariant, m_plugin.get());
297
298 bool returnValue = false;
299 NPVariantData resultData;
300
301 if (!m_connection->connection()->sendSync(Messages::PluginProxy::Evaluate(npObjectAsNPVariantData, scriptString, allowPopups), Messages::PluginProxy::Evaluate::Reply(returnValue, resultData), m_pluginInstanceID))
302 return false;
303
304 if (!returnValue)
305 return false;
306
307 *result = m_connection->npRemoteObjectMap()->npVariantDataToNPVariant(resultData, m_plugin.get());
308 return true;
309}
310
311void PluginControllerProxy::setPluginIsPlayingAudio(bool pluginIsPlayingAudio)
312{
313 m_connection->connection()->send(Messages::PluginProxy::SetPluginIsPlayingAudio(pluginIsPlayingAudio), m_pluginInstanceID);
314}
315
316void PluginControllerProxy::setStatusbarText(const String& statusbarText)
317{
318 m_connection->connection()->send(Messages::PluginProxy::SetStatusbarText(statusbarText), m_pluginInstanceID);
319}
320
321bool PluginControllerProxy::isAcceleratedCompositingEnabled()
322{
323 return m_isAcceleratedCompositingEnabled;
324}
325
326void PluginControllerProxy::pluginProcessCrashed()
327{
328 // This should never be called from here.
329 ASSERT_NOT_REACHED();
330}
331
332void PluginControllerProxy::didInitializePlugin()
333{
334 // This should only be called on the plugin in the web process.
335 ASSERT_NOT_REACHED();
336}
337
338void PluginControllerProxy::didFailToInitializePlugin()
339{
340 // This should only be called on the plugin in the web process.
341 ASSERT_NOT_REACHED();
342}
343
344float PluginControllerProxy::contentsScaleFactor()
345{
346 return m_contentsScaleFactor;
347}
348
349String PluginControllerProxy::proxiesForURL(const String& urlString)
350{
351 String proxyString;
352
353 if (!m_connection->connection()->sendSync(Messages::PluginProxy::ProxiesForURL(urlString), Messages::PluginProxy::ProxiesForURL::Reply(proxyString), m_pluginInstanceID))
354 return String();
355
356 return proxyString;
357}
358
359String PluginControllerProxy::cookiesForURL(const String& urlString)
360{
361 String cookieString;
362
363 if (!m_connection->connection()->sendSync(Messages::PluginProxy::CookiesForURL(urlString), Messages::PluginProxy::CookiesForURL::Reply(cookieString), m_pluginInstanceID))
364 return String();
365
366 return cookieString;
367}
368
369void PluginControllerProxy::setCookiesForURL(const String& urlString, const String& cookieString)
370{
371 m_connection->connection()->send(Messages::PluginProxy::SetCookiesForURL(urlString, cookieString), m_pluginInstanceID);
372}
373
374bool PluginControllerProxy::isPrivateBrowsingEnabled()
375{
376 return m_isPrivateBrowsingEnabled;
377}
378
379bool PluginControllerProxy::getAuthenticationInfo(const ProtectionSpace& protectionSpace, String& username, String& password)
380{
381 bool returnValue;
382 if (!m_connection->connection()->sendSync(Messages::PluginProxy::GetAuthenticationInfo(protectionSpace), Messages::PluginProxy::GetAuthenticationInfo::Reply(returnValue, username, password), m_pluginInstanceID))
383 return false;
384
385 return returnValue;
386}
387
388void PluginControllerProxy::protectPluginFromDestruction()
389{
390 m_pluginDestructionProtectCount++;
391}
392
393void PluginControllerProxy::unprotectPluginFromDestruction()
394{
395 ASSERT(m_pluginDestructionProtectCount);
396
397 m_pluginDestructionProtectCount--;
398}
399
400void PluginControllerProxy::frameDidFinishLoading(uint64_t requestID)
401{
402 m_plugin->frameDidFinishLoading(requestID);
403}
404
405void PluginControllerProxy::frameDidFail(uint64_t requestID, bool wasCancelled)
406{
407 m_plugin->frameDidFail(requestID, wasCancelled);
408}
409
410void PluginControllerProxy::geometryDidChange(const IntSize& pluginSize, const IntRect& clipRect, const AffineTransform& pluginToRootViewTransform, float contentsScaleFactor, const ShareableBitmap::Handle& backingStoreHandle)
411{
412 ASSERT(m_plugin);
413
414 m_pluginSize = pluginSize;
415
416 if (contentsScaleFactor != m_contentsScaleFactor) {
417 m_contentsScaleFactor = contentsScaleFactor;
418 m_plugin->contentsScaleFactorChanged(m_contentsScaleFactor);
419 }
420
421 platformGeometryDidChange();
422
423 if (!backingStoreHandle.isNull()) {
424 // Create a new backing store.
425 m_backingStore = ShareableBitmap::create(backingStoreHandle);
426 }
427
428 m_plugin->geometryDidChange(pluginSize, clipRect, pluginToRootViewTransform);
429}
430
431void PluginControllerProxy::visibilityDidChange(bool isVisible)
432{
433 m_isVisible = isVisible;
434
435 ASSERT(m_plugin);
436 m_plugin->visibilityDidChange(isVisible);
437
438 updateVisibilityActivity();
439}
440
441void PluginControllerProxy::windowFocusChanged(bool hasFocus)
442{
443 ASSERT(m_plugin);
444 m_plugin->windowFocusChanged(hasFocus);
445}
446
447void PluginControllerProxy::windowVisibilityChanged(bool isVisible)
448{
449 m_isWindowVisible = isVisible;
450
451 ASSERT(m_plugin);
452 m_plugin->windowVisibilityChanged(isVisible);
453
454 updateVisibilityActivity();
455}
456
457void PluginControllerProxy::updateVisibilityActivity()
458{
459 if (m_isVisible && m_isWindowVisible)
460 m_visiblityActivity.start();
461 else
462 m_visiblityActivity.stop();
463}
464
465void PluginControllerProxy::didEvaluateJavaScript(uint64_t requestID, const String& result)
466{
467 m_plugin->didEvaluateJavaScript(requestID, result);
468}
469
470void PluginControllerProxy::streamWillSendRequest(uint64_t streamID, const String& requestURLString, const String& redirectResponseURLString, uint32_t redirectResponseStatusCode)
471{
472 m_plugin->streamWillSendRequest(streamID, URL({ }, requestURLString), URL({ }, redirectResponseURLString), redirectResponseStatusCode);
473}
474
475void PluginControllerProxy::streamDidReceiveResponse(uint64_t streamID, const String& responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers)
476{
477 m_plugin->streamDidReceiveResponse(streamID, URL({ }, responseURLString), streamLength, lastModifiedTime, mimeType, headers, String());
478}
479
480void PluginControllerProxy::streamDidReceiveData(uint64_t streamID, const IPC::DataReference& data)
481{
482 m_plugin->streamDidReceiveData(streamID, reinterpret_cast<const char*>(data.data()), data.size());
483}
484
485void PluginControllerProxy::streamDidFinishLoading(uint64_t streamID)
486{
487 m_plugin->streamDidFinishLoading(streamID);
488}
489
490void PluginControllerProxy::streamDidFail(uint64_t streamID, bool wasCancelled)
491{
492 m_plugin->streamDidFail(streamID, wasCancelled);
493}
494
495void PluginControllerProxy::manualStreamDidReceiveResponse(const String& responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers)
496{
497 if (m_pluginCanceledManualStreamLoad)
498 return;
499
500 m_plugin->manualStreamDidReceiveResponse(URL({ }, responseURLString), streamLength, lastModifiedTime, mimeType, headers, String());
501}
502
503void PluginControllerProxy::manualStreamDidReceiveData(const IPC::DataReference& data)
504{
505 if (m_pluginCanceledManualStreamLoad)
506 return;
507
508 m_plugin->manualStreamDidReceiveData(reinterpret_cast<const char*>(data.data()), data.size());
509}
510
511void PluginControllerProxy::manualStreamDidFinishLoading()
512{
513 if (m_pluginCanceledManualStreamLoad)
514 return;
515
516 m_plugin->manualStreamDidFinishLoading();
517}
518
519void PluginControllerProxy::manualStreamDidFail(bool wasCancelled)
520{
521 if (m_pluginCanceledManualStreamLoad)
522 return;
523
524 m_plugin->manualStreamDidFail(wasCancelled);
525}
526
527void PluginControllerProxy::handleMouseEvent(const WebMouseEvent& mouseEvent)
528{
529 m_plugin->handleMouseEvent(mouseEvent);
530}
531
532void PluginControllerProxy::handleWheelEvent(const WebWheelEvent& wheelEvent, CompletionHandler<void(bool)>&& completionHandler)
533{
534 completionHandler(m_plugin->handleWheelEvent(wheelEvent));
535}
536
537void PluginControllerProxy::handleMouseEnterEvent(const WebMouseEvent& mouseEnterEvent, CompletionHandler<void(bool)>&& completionHandler)
538{
539 completionHandler(m_plugin->handleMouseEnterEvent(mouseEnterEvent));
540}
541
542void PluginControllerProxy::handleMouseLeaveEvent(const WebMouseEvent& mouseLeaveEvent, CompletionHandler<void(bool)>&& completionHandler)
543{
544 completionHandler(m_plugin->handleMouseLeaveEvent(mouseLeaveEvent));
545}
546
547void PluginControllerProxy::handleKeyboardEvent(const WebKeyboardEvent& keyboardEvent, CompletionHandler<void(bool)>&& completionHandler)
548{
549 completionHandler(m_plugin->handleKeyboardEvent(keyboardEvent));
550}
551
552void PluginControllerProxy::handleEditingCommand(const String& commandName, const String& argument, CompletionHandler<void(bool)>&& completionHandler)
553{
554 completionHandler(m_plugin->handleEditingCommand(commandName, argument));
555}
556
557void PluginControllerProxy::isEditingCommandEnabled(const String& commandName, CompletionHandler<void(bool)>&& completionHandler)
558{
559 completionHandler(m_plugin->isEditingCommandEnabled(commandName));
560}
561
562void PluginControllerProxy::handlesPageScaleFactor(CompletionHandler<void(bool)>&& completionHandler)
563{
564 completionHandler(m_plugin->handlesPageScaleFactor());
565}
566
567void PluginControllerProxy::requiresUnifiedScaleFactor(CompletionHandler<void(bool)>&& completionHandler)
568{
569 completionHandler(m_plugin->requiresUnifiedScaleFactor());
570}
571
572void PluginControllerProxy::paintEntirePlugin(CompletionHandler<void()>&& completionHandler)
573{
574 if (m_pluginSize.isEmpty())
575 return completionHandler();
576
577 m_dirtyRect = IntRect(IntPoint(), m_pluginSize);
578 paint();
579 completionHandler();
580}
581
582void PluginControllerProxy::supportsSnapshotting(CompletionHandler<void(bool)>&& completionHandler)
583{
584 completionHandler(m_plugin->supportsSnapshotting());
585}
586
587void PluginControllerProxy::snapshot(CompletionHandler<void(ShareableBitmap::Handle&&)> completionHandler)
588{
589 ASSERT(m_plugin);
590 RefPtr<ShareableBitmap> bitmap = m_plugin->snapshot();
591 if (!bitmap)
592 return completionHandler({ });
593
594 ShareableBitmap::Handle backingStoreHandle;
595 bitmap->createHandle(backingStoreHandle);
596 completionHandler(WTFMove(backingStoreHandle));
597}
598
599void PluginControllerProxy::setFocus(bool hasFocus)
600{
601 m_plugin->setFocus(hasFocus);
602}
603
604void PluginControllerProxy::didUpdate()
605{
606 m_waitingForDidUpdate = false;
607 startPaintTimer();
608}
609
610void PluginControllerProxy::getPluginScriptableNPObject(CompletionHandler<void(uint64_t)>&& completionHandler)
611{
612 NPObject* pluginScriptableNPObject = m_plugin->pluginScriptableNPObject();
613 if (!pluginScriptableNPObject)
614 return completionHandler(0);
615
616 uint64_t pluginScriptableNPObjectID = m_connection->npRemoteObjectMap()->registerNPObject(pluginScriptableNPObject, m_plugin.get());
617 releaseNPObject(pluginScriptableNPObject);
618 completionHandler(pluginScriptableNPObjectID);
619}
620
621void PluginControllerProxy::storageBlockingStateChanged(bool isStorageBlockingEnabled)
622{
623 if (m_storageBlockingEnabled != isStorageBlockingEnabled) {
624 m_storageBlockingEnabled = isStorageBlockingEnabled;
625 m_plugin->storageBlockingStateChanged(m_storageBlockingEnabled);
626 }
627}
628
629void PluginControllerProxy::privateBrowsingStateChanged(bool isPrivateBrowsingEnabled)
630{
631 m_isPrivateBrowsingEnabled = isPrivateBrowsingEnabled;
632
633 m_plugin->privateBrowsingStateChanged(isPrivateBrowsingEnabled);
634}
635
636void PluginControllerProxy::mutedStateChanged(bool isMuted)
637{
638 if (m_isMuted == isMuted)
639 return;
640
641 m_isMuted = isMuted;
642 m_plugin->mutedStateChanged(isMuted);
643}
644
645void PluginControllerProxy::getFormValue(CompletionHandler<void(bool, String&&)>&& completionHandler)
646{
647 String formValue;
648 bool returnValue = m_plugin->getFormValue(formValue);
649 completionHandler(returnValue, WTFMove(formValue));
650}
651
652#if PLATFORM(X11)
653uint64_t PluginControllerProxy::createPluginContainer()
654{
655 uint64_t windowID = 0;
656 m_connection->connection()->sendSync(Messages::PluginProxy::CreatePluginContainer(), Messages::PluginProxy::CreatePluginContainer::Reply(windowID), m_pluginInstanceID);
657 return windowID;
658}
659
660void PluginControllerProxy::windowedPluginGeometryDidChange(const IntRect& frameRect, const IntRect& clipRect, uint64_t windowID)
661{
662 m_connection->connection()->send(Messages::PluginProxy::WindowedPluginGeometryDidChange(frameRect, clipRect, windowID), m_pluginInstanceID);
663}
664
665void PluginControllerProxy::windowedPluginVisibilityDidChange(bool isVisible, uint64_t windowID)
666{
667 m_connection->connection()->send(Messages::PluginProxy::WindowedPluginVisibilityDidChange(isVisible, windowID), m_pluginInstanceID);
668}
669#endif
670
671} // namespace WebKit
672
673#endif // ENABLE(NETSCAPE_PLUGIN_API)
674