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 | |
54 | namespace WebKit { |
55 | using namespace WebCore; |
56 | |
57 | PluginControllerProxy::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 | |
82 | PluginControllerProxy::~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 | |
93 | void PluginControllerProxy::setInitializationReply(Messages::WebProcessConnection::CreatePlugin::DelayedReply&& reply) |
94 | { |
95 | ASSERT(!m_initializationReply); |
96 | m_initializationReply = WTFMove(reply); |
97 | } |
98 | |
99 | Messages::WebProcessConnection::CreatePlugin::DelayedReply PluginControllerProxy::takeInitializationReply() |
100 | { |
101 | return std::exchange(m_initializationReply, nullptr); |
102 | } |
103 | |
104 | bool 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 | |
141 | void 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 | |
166 | bool PluginControllerProxy::wantsWheelEvents() const |
167 | { |
168 | return m_plugin->wantsWheelEvents(); |
169 | } |
170 | |
171 | void 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 | |
201 | void 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 | |
222 | void 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 | |
233 | String PluginControllerProxy::userAgent() |
234 | { |
235 | return m_userAgent; |
236 | } |
237 | |
238 | void PluginControllerProxy::(uint64_t requestID, const String& method, const String& urlString, const String& target, const HTTPHeaderMap& , const Vector<uint8_t>& httpBody, bool ) |
239 | { |
240 | m_connection->connection()->send(Messages::PluginProxy::LoadURL(requestID, method, urlString, target, headerFields, httpBody, allowPopups), m_pluginInstanceID); |
241 | } |
242 | |
243 | void PluginControllerProxy::continueStreamLoad(uint64_t streamID) |
244 | { |
245 | m_connection->connection()->send(Messages::PluginProxy::ContinueStreamLoad(streamID), m_pluginInstanceID); |
246 | } |
247 | |
248 | void PluginControllerProxy::cancelStreamLoad(uint64_t streamID) |
249 | { |
250 | m_connection->connection()->send(Messages::PluginProxy::CancelStreamLoad(streamID), m_pluginInstanceID); |
251 | } |
252 | |
253 | void PluginControllerProxy::cancelManualStreamLoad() |
254 | { |
255 | m_pluginCanceledManualStreamLoad = true; |
256 | |
257 | m_connection->connection()->send(Messages::PluginProxy::CancelManualStreamLoad(), m_pluginInstanceID); |
258 | } |
259 | |
260 | NPObject* PluginControllerProxy::windowScriptNPObject() |
261 | { |
262 | if (!m_windowNPObject) |
263 | return 0; |
264 | |
265 | retainNPObject(m_windowNPObject); |
266 | return m_windowNPObject; |
267 | } |
268 | |
269 | NPObject* 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 | |
288 | bool PluginControllerProxy::evaluate(NPObject* npObject, const String& scriptString, NPVariant* result, bool ) |
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 | |
311 | void PluginControllerProxy::setPluginIsPlayingAudio(bool pluginIsPlayingAudio) |
312 | { |
313 | m_connection->connection()->send(Messages::PluginProxy::SetPluginIsPlayingAudio(pluginIsPlayingAudio), m_pluginInstanceID); |
314 | } |
315 | |
316 | void PluginControllerProxy::setStatusbarText(const String& statusbarText) |
317 | { |
318 | m_connection->connection()->send(Messages::PluginProxy::SetStatusbarText(statusbarText), m_pluginInstanceID); |
319 | } |
320 | |
321 | bool PluginControllerProxy::isAcceleratedCompositingEnabled() |
322 | { |
323 | return m_isAcceleratedCompositingEnabled; |
324 | } |
325 | |
326 | void PluginControllerProxy::pluginProcessCrashed() |
327 | { |
328 | // This should never be called from here. |
329 | ASSERT_NOT_REACHED(); |
330 | } |
331 | |
332 | void PluginControllerProxy::didInitializePlugin() |
333 | { |
334 | // This should only be called on the plugin in the web process. |
335 | ASSERT_NOT_REACHED(); |
336 | } |
337 | |
338 | void PluginControllerProxy::didFailToInitializePlugin() |
339 | { |
340 | // This should only be called on the plugin in the web process. |
341 | ASSERT_NOT_REACHED(); |
342 | } |
343 | |
344 | float PluginControllerProxy::contentsScaleFactor() |
345 | { |
346 | return m_contentsScaleFactor; |
347 | } |
348 | |
349 | String 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 | |
359 | String 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 | |
369 | void PluginControllerProxy::setCookiesForURL(const String& urlString, const String& cookieString) |
370 | { |
371 | m_connection->connection()->send(Messages::PluginProxy::SetCookiesForURL(urlString, cookieString), m_pluginInstanceID); |
372 | } |
373 | |
374 | bool PluginControllerProxy::isPrivateBrowsingEnabled() |
375 | { |
376 | return m_isPrivateBrowsingEnabled; |
377 | } |
378 | |
379 | bool 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 | |
388 | void PluginControllerProxy::protectPluginFromDestruction() |
389 | { |
390 | m_pluginDestructionProtectCount++; |
391 | } |
392 | |
393 | void PluginControllerProxy::unprotectPluginFromDestruction() |
394 | { |
395 | ASSERT(m_pluginDestructionProtectCount); |
396 | |
397 | m_pluginDestructionProtectCount--; |
398 | } |
399 | |
400 | void PluginControllerProxy::frameDidFinishLoading(uint64_t requestID) |
401 | { |
402 | m_plugin->frameDidFinishLoading(requestID); |
403 | } |
404 | |
405 | void PluginControllerProxy::frameDidFail(uint64_t requestID, bool wasCancelled) |
406 | { |
407 | m_plugin->frameDidFail(requestID, wasCancelled); |
408 | } |
409 | |
410 | void 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 | |
431 | void PluginControllerProxy::visibilityDidChange(bool isVisible) |
432 | { |
433 | m_isVisible = isVisible; |
434 | |
435 | ASSERT(m_plugin); |
436 | m_plugin->visibilityDidChange(isVisible); |
437 | |
438 | updateVisibilityActivity(); |
439 | } |
440 | |
441 | void PluginControllerProxy::windowFocusChanged(bool hasFocus) |
442 | { |
443 | ASSERT(m_plugin); |
444 | m_plugin->windowFocusChanged(hasFocus); |
445 | } |
446 | |
447 | void PluginControllerProxy::windowVisibilityChanged(bool isVisible) |
448 | { |
449 | m_isWindowVisible = isVisible; |
450 | |
451 | ASSERT(m_plugin); |
452 | m_plugin->windowVisibilityChanged(isVisible); |
453 | |
454 | updateVisibilityActivity(); |
455 | } |
456 | |
457 | void PluginControllerProxy::updateVisibilityActivity() |
458 | { |
459 | if (m_isVisible && m_isWindowVisible) |
460 | m_visiblityActivity.start(); |
461 | else |
462 | m_visiblityActivity.stop(); |
463 | } |
464 | |
465 | void PluginControllerProxy::didEvaluateJavaScript(uint64_t requestID, const String& result) |
466 | { |
467 | m_plugin->didEvaluateJavaScript(requestID, result); |
468 | } |
469 | |
470 | void 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 | |
475 | void PluginControllerProxy::streamDidReceiveResponse(uint64_t streamID, const String& responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& ) |
476 | { |
477 | m_plugin->streamDidReceiveResponse(streamID, URL({ }, responseURLString), streamLength, lastModifiedTime, mimeType, headers, String()); |
478 | } |
479 | |
480 | void 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 | |
485 | void PluginControllerProxy::streamDidFinishLoading(uint64_t streamID) |
486 | { |
487 | m_plugin->streamDidFinishLoading(streamID); |
488 | } |
489 | |
490 | void PluginControllerProxy::streamDidFail(uint64_t streamID, bool wasCancelled) |
491 | { |
492 | m_plugin->streamDidFail(streamID, wasCancelled); |
493 | } |
494 | |
495 | void PluginControllerProxy::manualStreamDidReceiveResponse(const String& responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& ) |
496 | { |
497 | if (m_pluginCanceledManualStreamLoad) |
498 | return; |
499 | |
500 | m_plugin->manualStreamDidReceiveResponse(URL({ }, responseURLString), streamLength, lastModifiedTime, mimeType, headers, String()); |
501 | } |
502 | |
503 | void 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 | |
511 | void PluginControllerProxy::manualStreamDidFinishLoading() |
512 | { |
513 | if (m_pluginCanceledManualStreamLoad) |
514 | return; |
515 | |
516 | m_plugin->manualStreamDidFinishLoading(); |
517 | } |
518 | |
519 | void PluginControllerProxy::manualStreamDidFail(bool wasCancelled) |
520 | { |
521 | if (m_pluginCanceledManualStreamLoad) |
522 | return; |
523 | |
524 | m_plugin->manualStreamDidFail(wasCancelled); |
525 | } |
526 | |
527 | void PluginControllerProxy::handleMouseEvent(const WebMouseEvent& mouseEvent) |
528 | { |
529 | m_plugin->handleMouseEvent(mouseEvent); |
530 | } |
531 | |
532 | void PluginControllerProxy::handleWheelEvent(const WebWheelEvent& wheelEvent, CompletionHandler<void(bool)>&& completionHandler) |
533 | { |
534 | completionHandler(m_plugin->handleWheelEvent(wheelEvent)); |
535 | } |
536 | |
537 | void PluginControllerProxy::handleMouseEnterEvent(const WebMouseEvent& mouseEnterEvent, CompletionHandler<void(bool)>&& completionHandler) |
538 | { |
539 | completionHandler(m_plugin->handleMouseEnterEvent(mouseEnterEvent)); |
540 | } |
541 | |
542 | void PluginControllerProxy::handleMouseLeaveEvent(const WebMouseEvent& mouseLeaveEvent, CompletionHandler<void(bool)>&& completionHandler) |
543 | { |
544 | completionHandler(m_plugin->handleMouseLeaveEvent(mouseLeaveEvent)); |
545 | } |
546 | |
547 | void PluginControllerProxy::handleKeyboardEvent(const WebKeyboardEvent& keyboardEvent, CompletionHandler<void(bool)>&& completionHandler) |
548 | { |
549 | completionHandler(m_plugin->handleKeyboardEvent(keyboardEvent)); |
550 | } |
551 | |
552 | void PluginControllerProxy::handleEditingCommand(const String& commandName, const String& argument, CompletionHandler<void(bool)>&& completionHandler) |
553 | { |
554 | completionHandler(m_plugin->handleEditingCommand(commandName, argument)); |
555 | } |
556 | |
557 | void PluginControllerProxy::isEditingCommandEnabled(const String& commandName, CompletionHandler<void(bool)>&& completionHandler) |
558 | { |
559 | completionHandler(m_plugin->isEditingCommandEnabled(commandName)); |
560 | } |
561 | |
562 | void PluginControllerProxy::handlesPageScaleFactor(CompletionHandler<void(bool)>&& completionHandler) |
563 | { |
564 | completionHandler(m_plugin->handlesPageScaleFactor()); |
565 | } |
566 | |
567 | void PluginControllerProxy::requiresUnifiedScaleFactor(CompletionHandler<void(bool)>&& completionHandler) |
568 | { |
569 | completionHandler(m_plugin->requiresUnifiedScaleFactor()); |
570 | } |
571 | |
572 | void 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 | |
582 | void PluginControllerProxy::supportsSnapshotting(CompletionHandler<void(bool)>&& completionHandler) |
583 | { |
584 | completionHandler(m_plugin->supportsSnapshotting()); |
585 | } |
586 | |
587 | void 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 | |
599 | void PluginControllerProxy::setFocus(bool hasFocus) |
600 | { |
601 | m_plugin->setFocus(hasFocus); |
602 | } |
603 | |
604 | void PluginControllerProxy::didUpdate() |
605 | { |
606 | m_waitingForDidUpdate = false; |
607 | startPaintTimer(); |
608 | } |
609 | |
610 | void 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 | |
621 | void PluginControllerProxy::storageBlockingStateChanged(bool isStorageBlockingEnabled) |
622 | { |
623 | if (m_storageBlockingEnabled != isStorageBlockingEnabled) { |
624 | m_storageBlockingEnabled = isStorageBlockingEnabled; |
625 | m_plugin->storageBlockingStateChanged(m_storageBlockingEnabled); |
626 | } |
627 | } |
628 | |
629 | void PluginControllerProxy::privateBrowsingStateChanged(bool isPrivateBrowsingEnabled) |
630 | { |
631 | m_isPrivateBrowsingEnabled = isPrivateBrowsingEnabled; |
632 | |
633 | m_plugin->privateBrowsingStateChanged(isPrivateBrowsingEnabled); |
634 | } |
635 | |
636 | void PluginControllerProxy::mutedStateChanged(bool isMuted) |
637 | { |
638 | if (m_isMuted == isMuted) |
639 | return; |
640 | |
641 | m_isMuted = isMuted; |
642 | m_plugin->mutedStateChanged(isMuted); |
643 | } |
644 | |
645 | void 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) |
653 | uint64_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 | |
660 | void 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 | |
665 | void 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 | |