Commit cf69686e authored by dino@apple.com's avatar dino@apple.com
Browse files

When a primary plugin is restarted, also start similar plugins

https://bugs.webkit.org/show_bug.cgi?id=113265

Reviewed by Tim Horton.

Source/WebCore:

If we detect a primary plugin that is snapshotted, we immediately restart it.
When this happens, we should also restart any other plugins that
match the same origin and type. This allows sites with a lot of
(geometrically) nearby plugins to behave as if they are a single big plugin.

Tests: plugins/snapshotting/autoplay-similar-to-dominant-after-delay.html
       plugins/snapshotting/autoplay-similar-to-dominant.html

* WebCore.exp.in: Export mimeTypeFromURL.
* html/HTMLPlugInImageElement.cpp:
(WebCore::addPlugInsFromNodeListMatchingPlugInOrigin): Use loadedMimeType helper.
(WebCore::HTMLPlugInImageElement::restartSimilarPlugIns): New method, which copied the
    existing code from userDidClickSnapshot.
(WebCore::HTMLPlugInImageElement::userDidClickSnapshot): Move the similar plugin detection
    out into another function and call it.
(WebCore::HTMLPlugInImageElement::setIsPrimarySnapshottedPlugIn): Call restartSimilarPlugIns.
(WebCore::HTMLPlugInImageElement::subframeLoaderWillCreatePlugIn): Use loadedMimeType helper.
* html/HTMLPlugInImageElement.h: Declaration of restartSimilarPlugIns.
(WebCore::HTMLPlugInImageElement::loadedMimeType): New helper method since this
    code was being often duplicated.

Source/WebKit2:

Remember the origin of the primary plugin, so that we can
autostart anything that is similar.

* WebProcess/WebCoreSupport/WebPlugInClient.cpp:
(WebKit::WebPlugInClient::WebPlugInClient): Keep a pointer to the WebPage.
(WebKit::WebPlugInClient::shouldAutoStartFromOrigin): Pass the page onto the process.
* WebProcess/WebCoreSupport/WebPlugInClient.h:
(WebPlugInClient): New member variable for the WebPage we were created with.
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::determinePrimarySnapshottedPlugIn): Remember the origin information
    for the primary plugin.
(WebKit::WebPage::matchesPrimaryPlugIn): Returns true if we're seeing something that
    looks like the primary plugin.
* WebProcess/WebPage/WebPage.h: New method matchesPrimaryPlugIn.
* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::shouldPlugInAutoStartFromOrigin): Check if the page thinks this is
    the primary plugin.
* WebProcess/WebProcess.h: Accept a reference to the page in shouldPlugInAutoStartFromOrigin.

LayoutTests:

Two new tests. The first has one big plugin (that should be detected as the primary)
and then a few smaller versions (which should autostart along with the primary).
The second has one big plugin, and then adds a similar one after a short delay.

* platform/mac-wk2/plugins/snapshotting/autoplay-similar-to-dominant-after-delay-expected.txt: Added.
* platform/mac-wk2/plugins/snapshotting/autoplay-similar-to-dominant-expected.txt: Added.
* plugins/snapshotting/autoplay-similar-to-dominant-after-delay.html: Added.
* plugins/snapshotting/autoplay-similar-to-dominant.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@146946 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 0e269132
2013-03-26 Dean Jackson <dino@apple.com>
When a primary plugin is restarted, also start similar plugins
https://bugs.webkit.org/show_bug.cgi?id=113265
Reviewed by Tim Horton.
Two new tests. The first has one big plugin (that should be detected as the primary)
and then a few smaller versions (which should autostart along with the primary).
The second has one big plugin, and then adds a similar one after a short delay.
* platform/mac-wk2/plugins/snapshotting/autoplay-similar-to-dominant-after-delay-expected.txt: Added.
* platform/mac-wk2/plugins/snapshotting/autoplay-similar-to-dominant-expected.txt: Added.
* plugins/snapshotting/autoplay-similar-to-dominant-after-delay.html: Added.
* plugins/snapshotting/autoplay-similar-to-dominant.html: Added.
2013-03-26 Zoltan Horvath <zoltan@webkit.org>
 
Unreviewed. Fix test after r146938. Since CSS Exclusions is still an experimental feature, shape-inside-on-nested-container-with-unresolved-height.html
layer at (0,0) size 785x850
RenderView at (0,0) size 785x600
layer at (0,0) size 785x850
RenderBlock {HTML} at (0,0) size 785x850
RenderBody {BODY} at (8,8) size 769x834
RenderBlock {P} at (0,0) size 769x18
RenderText {#text} at (0,0) size 696x18
text run at (0,0) width 696: "The dominant plugin should play automatically, and then so should the identical plugin that is added a bit later."
RenderBlock {DIV} at (0,34) size 769x600
RenderText {#text} at (0,0) size 0x0
RenderBlock {DIV} at (0,634) size 769x200
layer at (8,42) size 600x600
RenderEmbeddedObject {EMBED} at (0,0) size 600x600
layer at (8,642) size 200x200
RenderEmbeddedObject {EMBED} at (0,0) size 200x200
layer at (0,0) size 785x1056
RenderView at (0,0) size 785x600
layer at (0,0) size 785x1056
RenderBlock {HTML} at (0,0) size 785x1056
RenderBody {BODY} at (8,8) size 769x1032
RenderBlock {P} at (0,0) size 769x18
RenderText {#text} at (0,0) size 750x18
text run at (0,0) width 750: "The dominant plugin should play automatically, and trigger all the others to play as well, since they are the same origin."
RenderBlock {P} at (0,34) size 769x600
RenderText {#text} at (0,0) size 0x0
RenderBlock {P} at (0,650) size 769x200
RenderText {#text} at (0,0) size 0x0
RenderBlock {P} at (0,866) size 769x100
RenderText {#text} at (0,0) size 0x0
RenderBlock {P} at (0,982) size 769x50
RenderText {#text} at (0,0) size 0x0
layer at (8,42) size 600x600
RenderEmbeddedObject {EMBED} at (0,0) size 600x600
layer at (8,658) size 200x200
RenderEmbeddedObject {EMBED} at (0,0) size 200x200
layer at (8,874) size 100x100
RenderEmbeddedObject {EMBED} at (0,0) size 100x100
layer at (8,990) size 50x50
RenderEmbeddedObject {EMBED} at (0,0) size 50x50
<p>The dominant plugin should play automatically, and then so should the identical plugin that is added a bit later.</p>
<script>
if (window.testRunner) {
window.internals.settings.setPlugInSnapshottingEnabled(true);
window.internals.settings.setMaximumPlugInSnapshotAttempts(0);
testRunner.waitUntilDone();
setTimeout(function () {
var div = document.createElement("div");
div.innerHTML = '<embed src="../resources/simple_blank.swf" width="200" height="200"></embed>';
document.body.appendChild(div);
setTimeout(function () {
testRunner.notifyDone();
}, 500);
}, 500);
}
</script>
<div>
<embed src="../resources/simple_blank.swf" width="600" height="600"></embed>
</div>
<p>The dominant plugin should play automatically, and trigger all the others to play as well, since they are the same origin.</p>
<script>
if (window.testRunner) {
window.internals.settings.setPlugInSnapshottingEnabled(true);
window.internals.settings.setMaximumPlugInSnapshotAttempts(0);
testRunner.waitUntilDone();
setTimeout(function () {
testRunner.notifyDone();
}, 500);
}
</script>
<p>
<embed src="../resources/simple_blank.swf" width="600" height="600"></embed>
</p>
<p>
<embed src="../resources/simple_blank.swf" width="200" height="200"></embed>
</p>
<p>
<embed src="../resources/simple_blank.swf" width="100" height="100"></embed>
</p>
<p>
<embed src="../resources/simple_blank.swf" width="50" height="50"></embed>
</p>
2013-03-26 Dean Jackson <dino@apple.com>
When a primary plugin is restarted, also start similar plugins
https://bugs.webkit.org/show_bug.cgi?id=113265
Reviewed by Tim Horton.
If we detect a primary plugin that is snapshotted, we immediately restart it.
When this happens, we should also restart any other plugins that
match the same origin and type. This allows sites with a lot of
(geometrically) nearby plugins to behave as if they are a single big plugin.
Tests: plugins/snapshotting/autoplay-similar-to-dominant-after-delay.html
plugins/snapshotting/autoplay-similar-to-dominant.html
* WebCore.exp.in: Export mimeTypeFromURL.
* html/HTMLPlugInImageElement.cpp:
(WebCore::addPlugInsFromNodeListMatchingPlugInOrigin): Use loadedMimeType helper.
(WebCore::HTMLPlugInImageElement::restartSimilarPlugIns): New method, which copied the
existing code from userDidClickSnapshot.
(WebCore::HTMLPlugInImageElement::userDidClickSnapshot): Move the similar plugin detection
out into another function and call it.
(WebCore::HTMLPlugInImageElement::setIsPrimarySnapshottedPlugIn): Call restartSimilarPlugIns.
(WebCore::HTMLPlugInImageElement::subframeLoaderWillCreatePlugIn): Use loadedMimeType helper.
* html/HTMLPlugInImageElement.h: Declaration of restartSimilarPlugIns.
(WebCore::HTMLPlugInImageElement::loadedMimeType): New helper method since this
code was being often duplicated.
2013-03-26 Brent Fulgham <bfulgham@webkit.org>
 
[Windows, WinCairo] Scroll offset being applied to plugins during print operations.
......@@ -478,6 +478,7 @@ __ZN7WebCore15StringTruncator5widthERKN3WTF6StringERKNS_4FontENS0_24EnableRoundi
__ZN7WebCore15VisiblePositionC1ERKNS_8PositionENS_9EAffinityE
__ZN7WebCore15defaultLanguageEv
__ZN7WebCore15localizedStringEPKc
__ZN7WebCore15mimeTypeFromURLERKNS_4KURLE
__ZN7WebCore15originalURLDataEP5NSURL
__ZN7WebCore15pathGetFileNameERKN3WTF6StringE
__ZN7WebCore15reportExceptionEPN3JSC9ExecStateENS0_7JSValueEPNS_12CachedScriptE
......
......@@ -323,12 +323,6 @@ static AtomicString classNameForShadowRoot(const Node* node)
return plugInLargeSizeClassName;
}
void HTMLPlugInImageElement::setIsPrimarySnapshottedPlugIn(bool isPrimarySnapshottedPlugIn)
{
if (isPrimarySnapshottedPlugIn)
restartSnapshottedPlugIn();
}
void HTMLPlugInImageElement::updateSnapshotInfo()
{
ShadowRoot* root = userAgentShadowRoot();
......@@ -411,9 +405,7 @@ static void addPlugInsFromNodeListMatchingPlugInOrigin(HTMLPlugInImageElementLis
if (plugInElement->isPlugInImageElement() && plugInElement->displayState() <= HTMLPlugInElement::DisplayingSnapshot) {
HTMLPlugInImageElement* plugInImageElement = toHTMLPlugInImageElement(node);
const KURL& loadedURL = plugInImageElement->loadedUrl();
String otherMimeType = plugInImageElement->serviceType();
if (otherMimeType.isEmpty())
otherMimeType = mimeTypeFromURL(loadedURL);
String otherMimeType = plugInImageElement->loadedMimeType();
if (plugInOrigin == loadedURL.host() && mimeType == otherMimeType)
plugInList.append(plugInImageElement);
}
......@@ -421,21 +413,13 @@ static void addPlugInsFromNodeListMatchingPlugInOrigin(HTMLPlugInImageElementLis
}
}
void HTMLPlugInImageElement::userDidClickSnapshot(PassRefPtr<MouseEvent> event)
void HTMLPlugInImageElement::restartSimilarPlugIns()
{
m_pendingClickEventFromSnapshot = event;
String plugInOrigin = m_loadedUrl.host();
String mimeType = serviceType();
if (mimeType.isEmpty())
mimeType = mimeTypeFromURL(m_loadedUrl);
if (document()->page() && !SchemeRegistry::shouldTreatURLSchemeAsLocal(document()->page()->mainFrame()->document()->baseURL().protocol()))
document()->page()->plugInClient()->didStartFromOrigin(document()->page()->mainFrame()->document()->baseURL().host(), plugInOrigin, mimeType);
restartSnapshottedPlugIn();
// Restart any other snapshotted plugins in the page with the same origin. Note that they
// may be in different frames, so traverse from the top of the document.
String plugInOrigin = m_loadedUrl.host();
String mimeType = loadedMimeType();
HTMLPlugInImageElementList pluginsNeedingRestart;
if (!document()->page())
......@@ -462,6 +446,25 @@ void HTMLPlugInImageElement::userDidClickSnapshot(PassRefPtr<MouseEvent> event)
}
}
void HTMLPlugInImageElement::userDidClickSnapshot(PassRefPtr<MouseEvent> event)
{
m_pendingClickEventFromSnapshot = event;
String plugInOrigin = m_loadedUrl.host();
if (document()->page() && !SchemeRegistry::shouldTreatURLSchemeAsLocal(document()->page()->mainFrame()->document()->baseURL().protocol()))
document()->page()->plugInClient()->didStartFromOrigin(document()->page()->mainFrame()->document()->baseURL().host(), plugInOrigin, loadedMimeType());
restartSnapshottedPlugIn();
restartSimilarPlugIns();
}
void HTMLPlugInImageElement::setIsPrimarySnapshottedPlugIn(bool isPrimarySnapshottedPlugIn)
{
if (isPrimarySnapshottedPlugIn) {
restartSnapshottedPlugIn();
restartSimilarPlugIns();
}
}
void HTMLPlugInImageElement::restartSnapshottedPlugIn()
{
if (displayState() != RestartingWithPendingMouseClick)
......@@ -561,11 +564,7 @@ void HTMLPlugInImageElement::subframeLoaderWillCreatePlugIn(const KURL& url)
return;
}
String mimeType = serviceType();
if (mimeType.isEmpty())
mimeType = mimeTypeFromURL(url);
if (document()->page()->plugInClient()->shouldAutoStartFromOrigin(document()->page()->mainFrame()->document()->baseURL().host(), url.host(), mimeType)) {
if (document()->page()->plugInClient()->shouldAutoStartFromOrigin(document()->page()->mainFrame()->document()->baseURL().host(), url.host(), loadedMimeType())) {
LOG(Plugins, "%p Plug-in from (%s, %s) is marked to auto-start, set to play", this, document()->page()->mainFrame()->document()->baseURL().host().utf8().data(), url.host().utf8().data());
return;
}
......
......@@ -59,6 +59,15 @@ public:
const String& serviceType() const { return m_serviceType; }
const String& url() const { return m_url; }
const KURL& loadedUrl() const { return m_loadedUrl; }
const String loadedMimeType() const
{
String mimeType = serviceType();
if (mimeType.isEmpty())
mimeType = mimeTypeFromURL(m_loadedUrl);
return mimeType;
}
bool shouldPreferPlugInsForImages() const { return m_shouldPreferPlugInsForImages; }
// Public for FrameView::addWidgetToUpdate()
......@@ -118,6 +127,8 @@ private:
void swapRendererTimerFired(Timer<HTMLPlugInImageElement>*);
void restartSimilarPlugIns();
virtual bool isPlugInImageElement() const OVERRIDE { return true; }
bool m_needsWidgetUpdate;
......
2013-03-26 Dean Jackson <dino@apple.com>
When a primary plugin is restarted, also start similar plugins
https://bugs.webkit.org/show_bug.cgi?id=113265
Reviewed by Tim Horton.
Remember the origin of the primary plugin, so that we can
autostart anything that is similar.
* WebProcess/WebCoreSupport/WebPlugInClient.cpp:
(WebKit::WebPlugInClient::WebPlugInClient): Keep a pointer to the WebPage.
(WebKit::WebPlugInClient::shouldAutoStartFromOrigin): Pass the page onto the process.
* WebProcess/WebCoreSupport/WebPlugInClient.h:
(WebPlugInClient): New member variable for the WebPage we were created with.
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::determinePrimarySnapshottedPlugIn): Remember the origin information
for the primary plugin.
(WebKit::WebPage::matchesPrimaryPlugIn): Returns true if we're seeing something that
looks like the primary plugin.
* WebProcess/WebPage/WebPage.h: New method matchesPrimaryPlugIn.
* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::shouldPlugInAutoStartFromOrigin): Check if the page thinks this is
the primary plugin.
* WebProcess/WebProcess.h: Accept a reference to the page in shouldPlugInAutoStartFromOrigin.
2013-03-26 Alexey Proskuryakov <ap@apple.com>
 
Follow-up to:
......@@ -33,7 +33,8 @@
namespace WebKit {
WebPlugInClient::WebPlugInClient(WebPage*)
WebPlugInClient::WebPlugInClient(WebPage* page)
: m_page(page)
{
}
......@@ -48,7 +49,7 @@ void WebPlugInClient::pageDestroyed()
bool WebPlugInClient::shouldAutoStartFromOrigin(const String& pageOrigin, const String& pluginOrigin, const String& mimeType)
{
return WebProcess::shared().shouldPlugInAutoStartFromOrigin(pageOrigin, pluginOrigin, mimeType);
return WebProcess::shared().shouldPlugInAutoStartFromOrigin(m_page, pageOrigin, pluginOrigin, mimeType);
}
void WebPlugInClient::didStartFromOrigin(const String& pageOrigin, const String& pluginOrigin, const String& mimeType)
......
......@@ -40,6 +40,8 @@ private:
virtual void pageDestroyed();
virtual bool shouldAutoStartFromOrigin(const String& pageOrigin, const String& pluginOrigin, const String& mimeType);
virtual void didStartFromOrigin(const String& pageOrigin, const String& pluginOrigin, const String& mimeType);
WebPage* m_page;
};
} // namespace WebKit
......
......@@ -3949,6 +3949,9 @@ void WebPage::determinePrimarySnapshottedPlugIn()
return;
m_didFindPrimarySnapshottedPlugin = true;
m_primaryPlugInPageOrigin = m_page->mainFrame()->document()->baseURL().host();
m_primaryPlugInOrigin = candidatePlugIn->loadedUrl().host();
m_primaryPlugInMimeType = candidatePlugIn->loadedMimeType();
candidatePlugIn->setIsPrimarySnapshottedPlugIn(true);
}
......@@ -3958,6 +3961,14 @@ void WebPage::resetPrimarySnapshottedPlugIn()
m_readyToFindPrimarySnapshottedPlugin = false;
m_didFindPrimarySnapshottedPlugin = false;
}
bool WebPage::matchesPrimaryPlugIn(const String& pageOrigin, const String& pluginOrigin, const String& mimeType) const
{
if (!m_didFindPrimarySnapshottedPlugin)
return false;
return (pageOrigin == m_primaryPlugInPageOrigin && pluginOrigin == m_primaryPlugInOrigin && mimeType == m_primaryPlugInMimeType);
}
#endif // ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
PassRefPtr<Range> WebPage::currentSelectionAsRange()
......
......@@ -640,6 +640,7 @@ public:
#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
void determinePrimarySnapshottedPlugIn();
void resetPrimarySnapshottedPlugIn();
bool matchesPrimaryPlugIn(const String& pageOrigin, const String& pluginOrigin, const String& mimeType) const;
#endif
private:
......@@ -860,6 +861,9 @@ private:
#if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
bool m_readyToFindPrimarySnapshottedPlugin;
bool m_didFindPrimarySnapshottedPlugin;
String m_primaryPlugInPageOrigin;
String m_primaryPlugInOrigin;
String m_primaryPlugInMimeType;
#endif
#if PLATFORM(MAC)
......
......@@ -789,12 +789,18 @@ bool WebProcess::isPlugInAutoStartOriginHash(unsigned plugInOriginHash)
return currentTime() < it->value;
}
bool WebProcess::shouldPlugInAutoStartFromOrigin(const String& pageOrigin, const String& pluginOrigin, const String& mimeType)
bool WebProcess::shouldPlugInAutoStartFromOrigin(const WebPage* page, const String& pageOrigin, const String& pluginOrigin, const String& mimeType)
{
if (m_plugInAutoStartOrigins.contains(pluginOrigin))
return true;
// The plugin wasn't in the general whitelist, so check against the more explicit hash list.
#ifdef ENABLE_PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC
// The plugin wasn't in the general whitelist, so check if it similar to the primary plugin for the page (if we've found one).
if (page && page->matchesPrimaryPlugIn(pageOrigin, pluginOrigin, mimeType))
return true;
#endif
// Lastly check against the more explicit hash list.
return isPlugInAutoStartOriginHash(hashForPlugInOrigin(pageOrigin, pluginOrigin, mimeType));
}
......
......@@ -125,7 +125,7 @@ public:
void addVisitedLink(WebCore::LinkHash);
bool isLinkVisited(WebCore::LinkHash) const;
bool shouldPlugInAutoStartFromOrigin(const String& pageOrigin, const String& pluginOrigin, const String& mimeType);
bool shouldPlugInAutoStartFromOrigin(const WebPage*, const String& pageOrigin, const String& pluginOrigin, const String& mimeType);
void plugInDidStartFromOrigin(const String& pageOrigin, const String& pluginOrigin, const String& mimeType);
void plugInDidReceiveUserInteraction(unsigned plugInOriginHash);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment