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