diff options
| author | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2017-05-30 12:48:17 +0200 |
|---|---|---|
| committer | Oswald Buddenhagen <oswald.buddenhagen@qt.io> | 2017-05-30 12:48:17 +0200 |
| commit | 881da28418d380042aa95a97f0cbd42560a64f7c (patch) | |
| tree | a794dff3274695e99c651902dde93d934ea7a5af /Source/WebKit2/UIProcess/Plugins | |
| parent | 7e104c57a70fdf551bb3d22a5d637cdcbc69dbea (diff) | |
| parent | 0fcedcd17cc00d3dd44c718b3cb36c1033319671 (diff) | |
| download | qtwebkit-881da28418d380042aa95a97f0cbd42560a64f7c.tar.gz | |
Merge 'wip/next' into dev
Change-Id: Iff9ee5e23bb326c4371ec8ed81d56f2f05d680e9
Diffstat (limited to 'Source/WebKit2/UIProcess/Plugins')
17 files changed, 478 insertions, 1416 deletions
diff --git a/Source/WebKit2/UIProcess/Plugins/PlugInAutoStartProvider.cpp b/Source/WebKit2/UIProcess/Plugins/PlugInAutoStartProvider.cpp index fd0e1d9ee..25075924e 100644 --- a/Source/WebKit2/UIProcess/Plugins/PlugInAutoStartProvider.cpp +++ b/Source/WebKit2/UIProcess/Plugins/PlugInAutoStartProvider.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2012-2014 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,11 +26,11 @@ #include "config.h" #include "PlugInAutoStartProvider.h" -#include "ImmutableArray.h" -#include "ImmutableDictionary.h" -#include "WebContext.h" +#include "APIArray.h" +#include "APIDictionary.h" #include "WebContextClient.h" #include "WebProcessMessages.h" +#include "WebProcessPool.h" #include <wtf/CurrentTime.h> using namespace WebCore; @@ -39,9 +39,11 @@ static const double plugInAutoStartExpirationTimeThreshold = 30 * 24 * 60 * 60; namespace WebKit { -PlugInAutoStartProvider::PlugInAutoStartProvider(WebContext* context) - : m_context(context) +PlugInAutoStartProvider::PlugInAutoStartProvider(WebProcessPool* processPool) + : m_processPool(processPool) { + m_hashToOriginMap.add(SessionID::defaultSessionID(), HashMap<unsigned, String>()); + m_autoStartTable.add(SessionID::defaultSessionID(), AutoStartTable()); } static double expirationTimeFromNow() @@ -49,110 +51,141 @@ static double expirationTimeFromNow() return currentTime() + plugInAutoStartExpirationTimeThreshold; } -void PlugInAutoStartProvider::addAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash) +void PlugInAutoStartProvider::addAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash, SessionID sessionID) { - if (m_hashToOriginMap.contains(plugInOriginHash)) + auto sessionIterator = m_hashToOriginMap.find(sessionID); + if (sessionIterator == m_hashToOriginMap.end()) { + if (m_hashToOriginMap.get(SessionID::defaultSessionID()).contains(plugInOriginHash)) + return; + sessionIterator = m_hashToOriginMap.set(sessionID, HashMap<unsigned, String>()).iterator; + } else if (sessionIterator->value.contains(plugInOriginHash) || m_hashToOriginMap.get(SessionID::defaultSessionID()).contains(plugInOriginHash)) return; - AutoStartTable::iterator it = m_autoStartTable.find(pageOrigin); - if (it == m_autoStartTable.end()) - it = m_autoStartTable.add(pageOrigin, PlugInAutoStartOriginHash()).iterator; + AutoStartTable::iterator it = m_autoStartTable.add(sessionID, AutoStartTable()).iterator->value.add(pageOrigin, PlugInAutoStartOriginMap()).iterator; double expirationTime = expirationTimeFromNow(); it->value.set(plugInOriginHash, expirationTime); - m_hashToOriginMap.set(plugInOriginHash, pageOrigin); + sessionIterator->value.set(plugInOriginHash, pageOrigin); - m_context->sendToAllProcesses(Messages::WebProcess::DidAddPlugInAutoStartOriginHash(plugInOriginHash, expirationTime)); - m_context->client().plugInAutoStartOriginHashesChanged(m_context); + m_processPool->sendToAllProcesses(Messages::WebProcess::DidAddPlugInAutoStartOriginHash(plugInOriginHash, expirationTime, sessionID)); + + if (!sessionID.isEphemeral()) + m_processPool->client().plugInAutoStartOriginHashesChanged(m_processPool); } -PlugInAutoStartOriginHash PlugInAutoStartProvider::autoStartOriginHashesCopy() const +SessionPlugInAutoStartOriginMap PlugInAutoStartProvider::autoStartOriginHashesCopy() const { - PlugInAutoStartOriginHash copyMap; - AutoStartTable::const_iterator end = m_autoStartTable.end(); - for (AutoStartTable::const_iterator it = m_autoStartTable.begin(); it != end; ++it) { - PlugInAutoStartOriginHash::const_iterator mapEnd = it->value.end(); - for (PlugInAutoStartOriginHash::const_iterator mapIt = it->value.begin(); mapIt != mapEnd; ++mapIt) - copyMap.set(mapIt->key, mapIt->value); + SessionPlugInAutoStartOriginMap sessionMap; + + for (const auto& sessionKeyOriginHash : m_autoStartTable) { + PlugInAutoStartOriginMap& map = sessionMap.add(sessionKeyOriginHash.key, PlugInAutoStartOriginMap()).iterator->value; + for (const auto& keyOriginHash : sessionKeyOriginHash.value) { + for (const auto& originHash : keyOriginHash.value) + map.set(originHash.key, originHash.value); + } } - return copyMap; + return sessionMap; } -PassRefPtr<ImmutableDictionary> PlugInAutoStartProvider::autoStartOriginsTableCopy() const +Ref<API::Dictionary> PlugInAutoStartProvider::autoStartOriginsTableCopy() const { - ImmutableDictionary::MapType map; - AutoStartTable::const_iterator end = m_autoStartTable.end(); + API::Dictionary::MapType map; + double now = currentTime(); - for (AutoStartTable::const_iterator it = m_autoStartTable.begin(); it != end; ++it) { - ImmutableDictionary::MapType hashMap; - PlugInAutoStartOriginHash::const_iterator valueEnd = it->value.end(); - for (PlugInAutoStartOriginHash::const_iterator valueIt = it->value.begin(); valueIt != valueEnd; ++valueIt) { - if (now > valueIt->value) - continue; - hashMap.set(String::number(valueIt->key), WebDouble::create(valueIt->value)); + for (const auto& stringOriginHash : m_autoStartTable.get(SessionID::defaultSessionID())) { + API::Dictionary::MapType hashMap; + for (const auto& originHash : stringOriginHash.value) { + if (now <= originHash.value) + hashMap.set(String::number(originHash.key), API::Double::create(originHash.value)); } - if (hashMap.size()) - map.set(it->key, ImmutableDictionary::adopt(hashMap)); + map.set(stringOriginHash.key, API::Dictionary::create(WTFMove(hashMap))); } - return ImmutableDictionary::adopt(map); + return API::Dictionary::create(WTFMove(map)); } -void PlugInAutoStartProvider::setAutoStartOriginsTable(ImmutableDictionary& table) +void PlugInAutoStartProvider::setAutoStartOriginsTable(API::Dictionary& table) { + setAutoStartOriginsTableWithItemsPassingTest(table, [](double) { + return true; + }); +} + +void PlugInAutoStartProvider::setAutoStartOriginsFilteringOutEntriesAddedAfterTime(API::Dictionary& table, double time) +{ + double adjustedTimestamp = time + plugInAutoStartExpirationTimeThreshold; + setAutoStartOriginsTableWithItemsPassingTest(table, [adjustedTimestamp](double expirationTimestamp) { + return adjustedTimestamp > expirationTimestamp; + }); +} + +void PlugInAutoStartProvider::setAutoStartOriginsTableWithItemsPassingTest(API::Dictionary& table, std::function<bool(double expirationTimestamp)> isExpirationTimeAcceptable) +{ + ASSERT(isExpirationTimeAcceptable); + m_hashToOriginMap.clear(); m_autoStartTable.clear(); HashMap<unsigned, double> hashMap; + HashMap<unsigned, String>& hashToOriginMap = m_hashToOriginMap.add(SessionID::defaultSessionID(), HashMap<unsigned, String>()).iterator->value; + AutoStartTable& ast = m_autoStartTable.add(SessionID::defaultSessionID(), AutoStartTable()).iterator->value; - ImmutableDictionary::MapType::const_iterator end = table.map().end(); - for (ImmutableDictionary::MapType::const_iterator it = table.map().begin(); it != end; ++it) { - PlugInAutoStartOriginHash hashes; - ImmutableDictionary* hashesForPage = static_cast<ImmutableDictionary*>(it->value.get()); - ImmutableDictionary::MapType::const_iterator hashEnd = hashesForPage->map().end(); - for (ImmutableDictionary::MapType::const_iterator hashIt = hashesForPage->map().begin(); hashIt != hashEnd; ++hashIt) { + for (auto& strDict : table.map()) { + PlugInAutoStartOriginMap hashes; + for (auto& hashTime : static_cast<API::Dictionary*>(strDict.value.get())->map()) { bool ok; - unsigned hash = hashIt->key.toUInt(&ok); + unsigned hash = hashTime.key.toUInt(&ok); if (!ok) continue; - if (hashIt->value->type() != WebDouble::APIType) + if (hashTime.value->type() != API::Double::APIType) + continue; + + double expirationTime = static_cast<API::Double*>(hashTime.value.get())->value(); + if (!isExpirationTimeAcceptable(expirationTime)) continue; - double expirationTime = static_cast<WebDouble*>(hashIt->value.get())->value(); hashes.set(hash, expirationTime); hashMap.set(hash, expirationTime); - m_hashToOriginMap.set(hash, it->key); + hashToOriginMap.set(hash, strDict.key); } - m_autoStartTable.set(it->key, hashes); + if (!hashes.isEmpty()) + ast.set(strDict.key, hashes); } - m_context->sendToAllProcesses(Messages::WebProcess::ResetPlugInAutoStartOriginHashes(hashMap)); + m_processPool->sendToAllProcesses(Messages::WebProcess::ResetPlugInAutoStartOriginDefaultHashes(hashMap)); } -void PlugInAutoStartProvider::setAutoStartOriginsArray(ImmutableArray& originList) +void PlugInAutoStartProvider::setAutoStartOriginsArray(API::Array& originList) { m_autoStartOrigins.clear(); - for (size_t i = 0, length = originList.size(); i < length; ++i) { - if (originList.at(i)->type() != WebString::APIType) - continue; - m_autoStartOrigins.append(static_cast<WebString*>(originList.at(i))->string()); - } + for (const auto& string : originList.elementsOfType<API::String>()) + m_autoStartOrigins.append(string->string()); } -void PlugInAutoStartProvider::didReceiveUserInteraction(unsigned plugInOriginHash) +void PlugInAutoStartProvider::didReceiveUserInteraction(unsigned plugInOriginHash, SessionID sessionID) { - HashMap<unsigned, String>::const_iterator it = m_hashToOriginMap.find(plugInOriginHash); - if (it == m_hashToOriginMap.end()) { - ASSERT_NOT_REACHED(); - return; + HashMap<WebCore::SessionID, HashMap<unsigned, String>>::const_iterator sessionIterator = m_hashToOriginMap.find(sessionID); + HashMap<unsigned, String>::const_iterator it; + bool contains = false; + if (sessionIterator != m_hashToOriginMap.end()) { + it = sessionIterator->value.find(plugInOriginHash); + contains = it != sessionIterator->value.end(); + } + if (!contains) { + sessionIterator = m_hashToOriginMap.find(SessionID::defaultSessionID()); + it = sessionIterator->value.find(plugInOriginHash); + if (it == sessionIterator->value.end()) { + ASSERT_NOT_REACHED(); + return; + } } double newExpirationTime = expirationTimeFromNow(); - m_autoStartTable.find(it->value)->value.set(plugInOriginHash, newExpirationTime); - m_context->sendToAllProcesses(Messages::WebProcess::DidAddPlugInAutoStartOriginHash(plugInOriginHash, newExpirationTime)); - m_context->client().plugInAutoStartOriginHashesChanged(m_context); + m_autoStartTable.add(sessionID, AutoStartTable()).iterator->value.add(it->value, PlugInAutoStartOriginMap()).iterator->value.set(plugInOriginHash, newExpirationTime); + m_processPool->sendToAllProcesses(Messages::WebProcess::DidAddPlugInAutoStartOriginHash(plugInOriginHash, newExpirationTime, sessionID)); + m_processPool->client().plugInAutoStartOriginHashesChanged(m_processPool); } } // namespace WebKit diff --git a/Source/WebKit2/UIProcess/Plugins/PlugInAutoStartProvider.h b/Source/WebKit2/UIProcess/Plugins/PlugInAutoStartProvider.h index 87c81fe3a..fe6bc6f56 100644 --- a/Source/WebKit2/UIProcess/Plugins/PlugInAutoStartProvider.h +++ b/Source/WebKit2/UIProcess/Plugins/PlugInAutoStartProvider.h @@ -26,6 +26,8 @@ #ifndef PlugInAutoStartProvider_h #define PlugInAutoStartProvider_h +#include <WebCore/SessionID.h> +#include <functional> #include <wtf/HashMap.h> #include <wtf/HashSet.h> #include <wtf/Noncopyable.h> @@ -33,37 +35,45 @@ #include <wtf/text/StringHash.h> #include <wtf/text/WTFString.h> +namespace API { +class Array; +class Dictionary; +} + namespace WebKit { -class ImmutableArray; -class ImmutableDictionary; -class WebContext; +class WebProcessPool; -typedef HashMap<unsigned, double> PlugInAutoStartOriginHash; +typedef HashMap<unsigned, double> PlugInAutoStartOriginMap; +typedef HashMap<WebCore::SessionID, PlugInAutoStartOriginMap> SessionPlugInAutoStartOriginMap; typedef Vector<String> PlugInAutoStartOrigins; class PlugInAutoStartProvider { WTF_MAKE_NONCOPYABLE(PlugInAutoStartProvider); public: - explicit PlugInAutoStartProvider(WebContext*); + explicit PlugInAutoStartProvider(WebProcessPool*); - void addAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash); - void didReceiveUserInteraction(unsigned plugInOriginHash); + void addAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash, WebCore::SessionID); + void didReceiveUserInteraction(unsigned plugInOriginHash, WebCore::SessionID); - PassRefPtr<ImmutableDictionary> autoStartOriginsTableCopy() const; - void setAutoStartOriginsTable(ImmutableDictionary&); - void setAutoStartOriginsArray(ImmutableArray&); + Ref<API::Dictionary> autoStartOriginsTableCopy() const; + void setAutoStartOriginsTable(API::Dictionary&); + void setAutoStartOriginsFilteringOutEntriesAddedAfterTime(API::Dictionary&, double time); + void setAutoStartOriginsArray(API::Array&); - PlugInAutoStartOriginHash autoStartOriginHashesCopy() const; + SessionPlugInAutoStartOriginMap autoStartOriginHashesCopy() const; const PlugInAutoStartOrigins& autoStartOrigins() const { return m_autoStartOrigins; } private: - WebContext* m_context; + WebProcessPool* m_processPool; + + void setAutoStartOriginsTableWithItemsPassingTest(API::Dictionary&, std::function<bool(double expirationTimestamp)>); - typedef HashMap<String, PlugInAutoStartOriginHash, CaseFoldingHash> AutoStartTable; - AutoStartTable m_autoStartTable; + typedef HashMap<String, PlugInAutoStartOriginMap, ASCIICaseInsensitiveHash> AutoStartTable; + typedef HashMap<WebCore::SessionID, AutoStartTable> SessionAutoStartTable; + SessionAutoStartTable m_autoStartTable; - HashMap<unsigned, String> m_hashToOriginMap; + HashMap<WebCore::SessionID, HashMap<unsigned, String>> m_hashToOriginMap; PlugInAutoStartOrigins m_autoStartOrigins; }; diff --git a/Source/WebKit2/UIProcess/Plugins/PluginInfoStore.cpp b/Source/WebKit2/UIProcess/Plugins/PluginInfoStore.cpp index ae95a0b68..eeb5087da 100644 --- a/Source/WebKit2/UIProcess/Plugins/PluginInfoStore.cpp +++ b/Source/WebKit2/UIProcess/Plugins/PluginInfoStore.cpp @@ -29,7 +29,7 @@ #if ENABLE(NETSCAPE_PLUGIN_API) #include "PluginModuleInfo.h" -#include <WebCore/KURL.h> +#include <WebCore/URL.h> #include <WebCore/MIMETypeRegistry.h> #include <algorithm> #include <wtf/ListHashSet.h> @@ -66,9 +66,9 @@ static void addFromVector(T& hashSet, const U& vector) // We use a ListHashSet so that plugins will be loaded from the additional plugins directories first // (which in turn means those plugins will be preferred if two plugins claim the same MIME type). #if OS(WINDOWS) -typedef ListHashSet<String, 32, CaseFoldingHash> PathHashSet; +typedef ListHashSet<String, ASCIICaseInsensitiveHash> PathHashSet; #else -typedef ListHashSet<String, 32> PathHashSet; +typedef ListHashSet<String> PathHashSet; #endif void PluginInfoStore::loadPluginsIfNecessary() @@ -92,9 +92,8 @@ void PluginInfoStore::loadPluginsIfNecessary() m_plugins.clear(); - PathHashSet::const_iterator end = uniquePluginPaths.end(); - for (PathHashSet::const_iterator it = uniquePluginPaths.begin(); it != end; ++it) - loadPlugin(m_plugins, *it); + for (const auto& pluginPath : uniquePluginPaths) + loadPlugin(m_plugins, pluginPath); m_pluginListIsUpToDate = true; @@ -124,15 +123,12 @@ Vector<PluginModuleInfo> PluginInfoStore::plugins() PluginModuleInfo PluginInfoStore::findPluginForMIMEType(const String& mimeType, PluginData::AllowedPluginTypes allowedPluginTypes) const { ASSERT(!mimeType.isNull()); - - for (size_t i = 0; i < m_plugins.size(); ++i) { - const PluginModuleInfo& plugin = m_plugins[i]; + for (const auto& plugin : m_plugins) { if (allowedPluginTypes == PluginData::OnlyApplicationPlugins && !plugin.info.isApplicationPlugin) continue; - - for (size_t j = 0; j < plugin.info.mimes.size(); ++j) { - const MimeClassInfo& mimeClassInfo = plugin.info.mimes[j]; + + for (const auto& mimeClassInfo : plugin.info.mimes) { if (mimeClassInfo.type == mimeType) return plugin; } @@ -144,19 +140,13 @@ PluginModuleInfo PluginInfoStore::findPluginForMIMEType(const String& mimeType, PluginModuleInfo PluginInfoStore::findPluginForExtension(const String& extension, String& mimeType, PluginData::AllowedPluginTypes allowedPluginTypes) const { ASSERT(!extension.isNull()); - - for (size_t i = 0; i < m_plugins.size(); ++i) { - const PluginModuleInfo& plugin = m_plugins[i]; + for (const auto& plugin : m_plugins) { if (allowedPluginTypes == PluginData::OnlyApplicationPlugins && !plugin.info.isApplicationPlugin) continue; - for (size_t j = 0; j < plugin.info.mimes.size(); ++j) { - const MimeClassInfo& mimeClassInfo = plugin.info.mimes[j]; - - const Vector<String>& extensions = mimeClassInfo.extensions; - - if (std::find(extensions.begin(), extensions.end(), extension) != extensions.end()) { + for (const auto& mimeClassInfo : plugin.info.mimes) { + if (mimeClassInfo.extensions.contains(extension)) { // We found a supported extension, set the correct MIME type. mimeType = mimeClassInfo.type; return plugin; @@ -167,29 +157,24 @@ PluginModuleInfo PluginInfoStore::findPluginForExtension(const String& extension return PluginModuleInfo(); } -static inline String pathExtension(const KURL& url) +static inline String pathExtension(const URL& url) { String extension; String filename = url.lastPathComponent(); if (!filename.endsWith('/')) { - int extensionPos = filename.reverseFind('.'); - if (extensionPos != -1) + size_t extensionPos = filename.reverseFind('.'); + if (extensionPos != notFound) extension = filename.substring(extensionPos + 1); } - - return extension; + return extension.convertToASCIILowercase(); } -#if !PLATFORM(MAC) +#if !PLATFORM(COCOA) + PluginModuleLoadPolicy PluginInfoStore::defaultLoadPolicyForPlugin(const PluginModuleInfo&) { return PluginModuleLoadNormally; } - -String PluginInfoStore::getMIMETypeForExtension(const String& extension) -{ - return MIMETypeRegistry::getMIMETypeForExtension(extension); -} PluginModuleInfo PluginInfoStore::findPluginWithBundleIdentifier(const String&) { @@ -199,7 +184,7 @@ PluginModuleInfo PluginInfoStore::findPluginWithBundleIdentifier(const String&) #endif -PluginModuleInfo PluginInfoStore::findPlugin(String& mimeType, const KURL& url, PluginData::AllowedPluginTypes allowedPluginTypes) +PluginModuleInfo PluginInfoStore::findPlugin(String& mimeType, const URL& url, PluginData::AllowedPluginTypes allowedPluginTypes) { loadPluginsIfNecessary(); @@ -211,14 +196,14 @@ PluginModuleInfo PluginInfoStore::findPlugin(String& mimeType, const KURL& url, } // Next, check if any plug-ins claim to support the URL extension. - String extension = pathExtension(url).lower(); + String extension = pathExtension(url); if (!extension.isNull() && mimeType.isEmpty()) { PluginModuleInfo plugin = findPluginForExtension(extension, mimeType, allowedPluginTypes); if (!plugin.path.isNull()) return plugin; // Finally, try to get the MIME type from the extension in a platform specific manner and use that. - String extensionMimeType = getMIMETypeForExtension(extension); + String extensionMimeType = MIMETypeRegistry::getMIMETypeForExtension(extension); if (!extensionMimeType.isNull()) { PluginModuleInfo plugin = findPluginForMIMEType(extensionMimeType, allowedPluginTypes); if (!plugin.path.isNull()) { @@ -233,11 +218,11 @@ PluginModuleInfo PluginInfoStore::findPlugin(String& mimeType, const KURL& url, PluginModuleInfo PluginInfoStore::infoForPluginWithPath(const String& pluginPath) const { - for (size_t i = 0; i < m_plugins.size(); ++i) { - if (m_plugins[i].path == pluginPath) - return m_plugins[i]; + for (const auto& plugin : m_plugins) { + if (plugin.path == pluginPath) + return plugin; } - + ASSERT_NOT_REACHED(); return PluginModuleInfo(); } diff --git a/Source/WebKit2/UIProcess/Plugins/PluginInfoStore.h b/Source/WebKit2/UIProcess/Plugins/PluginInfoStore.h index c49cea7b9..7b4f509c7 100644 --- a/Source/WebKit2/UIProcess/Plugins/PluginInfoStore.h +++ b/Source/WebKit2/UIProcess/Plugins/PluginInfoStore.h @@ -33,7 +33,7 @@ #include <WebCore/PluginData.h> namespace WebCore { - class KURL; + class URL; } namespace WebKit { @@ -63,7 +63,7 @@ public: // Returns the info for a plug-in that can handle the given MIME type. // If the MIME type is null, the file extension of the given url will be used to infer the // plug-in type. In that case, mimeType will be filled in with the right MIME type. - PluginModuleInfo findPlugin(String& mimeType, const WebCore::KURL&, WebCore::PluginData::AllowedPluginTypes = WebCore::PluginData::AllPlugins); + PluginModuleInfo findPlugin(String& mimeType, const WebCore::URL&, WebCore::PluginData::AllowedPluginTypes = WebCore::PluginData::AllPlugins); // Returns the info for the plug-in with the given bundle identifier. PluginModuleInfo findPluginWithBundleIdentifier(const String& bundleIdentifier); @@ -100,9 +100,6 @@ private: // Return whether this plug-in should be used (added to the list of plug-ins) or not. static bool shouldUsePlugin(Vector<PluginModuleInfo>& alreadyLoadedPlugins, const PluginModuleInfo&); - // Get the MIME type for the given extension. - static String getMIMETypeForExtension(const String& extension); - Vector<String> m_additionalPluginsDirectories; Vector<PluginModuleInfo> m_plugins; bool m_pluginListIsUpToDate; diff --git a/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.cpp b/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.cpp index e89accaf4..47eaa0950 100644 --- a/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.cpp +++ b/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.cpp @@ -26,23 +26,25 @@ #include "config.h" #include "PluginProcessManager.h" -#if ENABLE(PLUGIN_PROCESS) +#if ENABLE(NETSCAPE_PLUGIN_API) #include "PluginProcessProxy.h" -#include "WebContext.h" #include <wtf/CryptographicallyRandomNumber.h> #include <wtf/StdLibExtras.h> #include <wtf/text/WTFString.h> namespace WebKit { -PluginProcessManager& PluginProcessManager::shared() +PluginProcessManager& PluginProcessManager::singleton() { - DEFINE_STATIC_LOCAL(PluginProcessManager, pluginProcessManager, ()); + static NeverDestroyed<PluginProcessManager> pluginProcessManager; return pluginProcessManager; } PluginProcessManager::PluginProcessManager() +#if PLATFORM(COCOA) + : m_processSuppressionDisabledForPageCounter([this](bool value) { updateProcessSuppressionDisabled(value); }) +#endif { } @@ -71,11 +73,7 @@ uint64_t PluginProcessManager::pluginProcessToken(const PluginModuleInfo& plugin attributes.processType = pluginProcessType; attributes.sandboxPolicy = pluginProcessSandboxPolicy; -#if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) - m_pluginProcessTokens.append(std::make_pair(std::move(attributes), token)); -#else - m_pluginProcessTokens.append(std::make_pair(attributes, token)); -#endif + m_pluginProcessTokens.append(std::make_pair(WTFMove(attributes), token)); m_knownTokens.add(token); return token; @@ -97,16 +95,24 @@ void PluginProcessManager::removePluginProcessProxy(PluginProcessProxy* pluginPr m_pluginProcesses.remove(vectorIndex); } -void PluginProcessManager::getSitesWithData(const PluginModuleInfo& plugin, WebPluginSiteDataManager* webPluginSiteDataManager, uint64_t callbackID) +void PluginProcessManager::fetchWebsiteData(const PluginModuleInfo& plugin, std::function<void (Vector<String>)> completionHandler) +{ + PluginProcessProxy* pluginProcess = getOrCreatePluginProcess(pluginProcessToken(plugin, PluginProcessTypeNormal, PluginProcessSandboxPolicyNormal)); + + pluginProcess->fetchWebsiteData(WTFMove(completionHandler)); +} + +void PluginProcessManager::deleteWebsiteData(const PluginModuleInfo& plugin, std::chrono::system_clock::time_point modifiedSince, std::function<void ()> completionHandler) { PluginProcessProxy* pluginProcess = getOrCreatePluginProcess(pluginProcessToken(plugin, PluginProcessTypeNormal, PluginProcessSandboxPolicyNormal)); - pluginProcess->getSitesWithData(webPluginSiteDataManager, callbackID); + + pluginProcess->deleteWebsiteData(modifiedSince, WTFMove(completionHandler)); } -void PluginProcessManager::clearSiteData(const PluginModuleInfo& plugin, WebPluginSiteDataManager* webPluginSiteDataManager, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID) +void PluginProcessManager::deleteWebsiteDataForHostNames(const PluginModuleInfo& plugin, const Vector<String>& hostNames, std::function<void ()> completionHandler) { PluginProcessProxy* pluginProcess = getOrCreatePluginProcess(pluginProcessToken(plugin, PluginProcessTypeNormal, PluginProcessSandboxPolicyNormal)); - pluginProcess->clearSiteData(webPluginSiteDataManager, sites, flags, maxAgeInSeconds, callbackID); + pluginProcess->deleteWebsiteDataForHostNames(hostNames, WTFMove(completionHandler)); } PluginProcessProxy* PluginProcessManager::getOrCreatePluginProcess(uint64_t pluginProcessToken) @@ -117,7 +123,7 @@ PluginProcessProxy* PluginProcessManager::getOrCreatePluginProcess(uint64_t plug } for (size_t i = 0; i < m_pluginProcessTokens.size(); ++i) { - std::pair<PluginProcessAttributes, uint64_t>& attributesAndToken = m_pluginProcessTokens[i]; + auto& attributesAndToken = m_pluginProcessTokens[i]; if (attributesAndToken.second == pluginProcessToken) { RefPtr<PluginProcessProxy> pluginProcess = PluginProcessProxy::create(this, attributesAndToken.first, attributesAndToken.second); PluginProcessProxy* pluginProcessPtr = pluginProcess.get(); @@ -127,9 +133,9 @@ PluginProcessProxy* PluginProcessManager::getOrCreatePluginProcess(uint64_t plug } } - return 0; + return nullptr; } } // namespace WebKit -#endif // ENABLE(PLUGIN_PROCESS) +#endif // ENABLE(NETSCAPE_PLUGIN_API) diff --git a/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.h b/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.h index 0ffd4099a..8152125da 100644 --- a/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.h +++ b/Source/WebKit2/UIProcess/Plugins/PluginProcessManager.h @@ -26,18 +26,21 @@ #ifndef PluginProcessManager_h #define PluginProcessManager_h -#if ENABLE(PLUGIN_PROCESS) +#if ENABLE(NETSCAPE_PLUGIN_API) #include "PluginModuleInfo.h" #include "PluginProcess.h" #include "PluginProcessAttributes.h" +#include "ProcessThrottler.h" #include "WebProcessProxyMessages.h" #include <wtf/Forward.h> #include <wtf/HashSet.h> +#include <wtf/NeverDestroyed.h> #include <wtf/Noncopyable.h> +#include <wtf/RefCounter.h> #include <wtf/Vector.h> -namespace CoreIPC { +namespace IPC { class ArgumentEncoder; } @@ -46,23 +49,26 @@ namespace WebKit { class PluginInfoStore; class PluginProcessProxy; class WebProcessProxy; -class WebPluginSiteDataManager; class PluginProcessManager { WTF_MAKE_NONCOPYABLE(PluginProcessManager); + friend class NeverDestroyed<PluginProcessManager>; public: - static PluginProcessManager& shared(); + static PluginProcessManager& singleton(); uint64_t pluginProcessToken(const PluginModuleInfo&, PluginProcessType, PluginProcessSandboxPolicy); void getPluginProcessConnection(uint64_t pluginProcessToken, PassRefPtr<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply>); void removePluginProcessProxy(PluginProcessProxy*); - void getSitesWithData(const PluginModuleInfo&, WebPluginSiteDataManager*, uint64_t callbackID); - void clearSiteData(const PluginModuleInfo&, WebPluginSiteDataManager*, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID); + void fetchWebsiteData(const PluginModuleInfo&, std::function<void (Vector<String>)> completionHandler); + void deleteWebsiteData(const PluginModuleInfo&, std::chrono::system_clock::time_point modifiedSince, std::function<void ()> completionHandler); + void deleteWebsiteDataForHostNames(const PluginModuleInfo&, const Vector<String>& hostNames, std::function<void ()> completionHandler); -#if PLATFORM(MAC) - void setProcessSuppressionEnabled(bool); +#if PLATFORM(COCOA) + inline ProcessSuppressionDisabledToken processSuppressionDisabledToken(); + inline bool processSuppressionDisabled() const; + void updateProcessSuppressionDisabled(bool); #endif private: @@ -70,14 +76,30 @@ private: PluginProcessProxy* getOrCreatePluginProcess(uint64_t pluginProcessToken); - Vector<std::pair<PluginProcessAttributes, uint64_t> > m_pluginProcessTokens; + Vector<std::pair<PluginProcessAttributes, uint64_t>> m_pluginProcessTokens; HashSet<uint64_t> m_knownTokens; - Vector<RefPtr<PluginProcessProxy> > m_pluginProcesses; + Vector<RefPtr<PluginProcessProxy>> m_pluginProcesses; + +#if PLATFORM(COCOA) + RefCounter m_processSuppressionDisabledForPageCounter; +#endif }; +#if PLATFORM(COCOA) +inline ProcessSuppressionDisabledToken PluginProcessManager::processSuppressionDisabledToken() +{ + return m_processSuppressionDisabledForPageCounter.token<ProcessSuppressionDisabledTokenType>(); +} + +inline bool PluginProcessManager::processSuppressionDisabled() const +{ + return m_processSuppressionDisabledForPageCounter.value(); +} +#endif + } // namespace WebKit -#endif // ENABLE(PLUGIN_PROCESS) +#endif // ENABLE(NETSCAPE_PLUGIN_API) #endif // PluginProcessManager_h diff --git a/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.cpp b/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.cpp index 107ad1633..9bc7a04c7 100644 --- a/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.cpp +++ b/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.cpp @@ -26,22 +26,17 @@ #include "config.h" #include "PluginProcessProxy.h" -#if ENABLE(PLUGIN_PROCESS) +#if ENABLE(NETSCAPE_PLUGIN_API) #include "PluginProcessConnectionManagerMessages.h" #include "PluginProcessCreationParameters.h" #include "PluginProcessManager.h" #include "PluginProcessMessages.h" -#include "WebContext.h" #include "WebCoreArgumentCoders.h" -#include "WebPluginSiteDataManager.h" +#include "WebProcessPool.h" #include "WebProcessProxy.h" #include <WebCore/NotImplemented.h> -#include <WebCore/RunLoop.h> - -#if PLATFORM(MAC) -#include "MachPort.h" -#endif +#include <wtf/RunLoop.h> using namespace WebCore; @@ -53,9 +48,16 @@ static const double snapshottingMinimumLifetime = 30; static const double shutdownTimeout = 1 * 60; static const double snapshottingShutdownTimeout = 15; -PassRefPtr<PluginProcessProxy> PluginProcessProxy::create(PluginProcessManager* PluginProcessManager, const PluginProcessAttributes& pluginProcessAttributes, uint64_t pluginProcessToken) +static uint64_t generateCallbackID() { - return adoptRef(new PluginProcessProxy(PluginProcessManager, pluginProcessAttributes, pluginProcessToken)); + static uint64_t callbackID; + + return ++callbackID; +} + +Ref<PluginProcessProxy> PluginProcessProxy::create(PluginProcessManager* PluginProcessManager, const PluginProcessAttributes& pluginProcessAttributes, uint64_t pluginProcessToken) +{ + return adoptRef(*new PluginProcessProxy(PluginProcessManager, pluginProcessAttributes, pluginProcessToken)); } PluginProcessProxy::PluginProcessProxy(PluginProcessManager* PluginProcessManager, const PluginProcessAttributes& pluginProcessAttributes, uint64_t pluginProcessToken) @@ -63,7 +65,7 @@ PluginProcessProxy::PluginProcessProxy(PluginProcessManager* PluginProcessManage , m_pluginProcessAttributes(pluginProcessAttributes) , m_pluginProcessToken(pluginProcessToken) , m_numPendingConnectionRequests(0) -#if PLATFORM(MAC) +#if PLATFORM(COCOA) , m_modalWindowIsShowing(false) , m_fullscreenWindowIsShowing(false) , m_preFullscreenAppPresentationOptions(0) @@ -74,61 +76,76 @@ PluginProcessProxy::PluginProcessProxy(PluginProcessManager* PluginProcessManage PluginProcessProxy::~PluginProcessProxy() { + ASSERT(m_pendingFetchWebsiteDataRequests.isEmpty()); + ASSERT(m_pendingFetchWebsiteDataCallbacks.isEmpty()); + ASSERT(m_pendingDeleteWebsiteDataRequests.isEmpty()); + ASSERT(m_pendingDeleteWebsiteDataCallbacks.isEmpty()); } void PluginProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions) { - launchOptions.processType = ProcessLauncher::PluginProcess; + ChildProcessProxy::getLaunchOptions(launchOptions); platformGetLaunchOptions(launchOptions, m_pluginProcessAttributes); } +void PluginProcessProxy::processWillShutDown(IPC::Connection& connection) +{ + ASSERT_UNUSED(connection, this->connection() == &connection); +} + // Asks the plug-in process to create a new connection to a web process. The connection identifier will be // encoded in the given argument encoder and sent back to the connection of the given web process. void PluginProcessProxy::getPluginProcessConnection(PassRefPtr<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply> reply) { m_pendingConnectionReplies.append(reply); - if (isLaunching()) { + if (state() == State::Launching) { m_numPendingConnectionRequests++; return; } // Ask the plug-in process to create a connection. Since the plug-in can be waiting for a synchronous reply // we need to make sure that this message is always processed, even when the plug-in is waiting for a synchronus reply. - m_connection->send(Messages::PluginProcess::CreateWebProcessConnection(), 0, CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply); + m_connection->send(Messages::PluginProcess::CreateWebProcessConnection(), 0, IPC::DispatchMessageEvenWhenWaitingForSyncReply); } -void PluginProcessProxy::getSitesWithData(WebPluginSiteDataManager* webPluginSiteDataManager, uint64_t callbackID) +void PluginProcessProxy::fetchWebsiteData(std::function<void (Vector<String>)> completionHandler) { - ASSERT(!m_pendingGetSitesReplies.contains(callbackID)); - m_pendingGetSitesReplies.set(callbackID, webPluginSiteDataManager); + uint64_t callbackID = generateCallbackID(); + m_pendingFetchWebsiteDataCallbacks.set(callbackID, WTFMove(completionHandler)); - if (isLaunching()) { - m_pendingGetSitesRequests.append(callbackID); + if (state() == State::Launching) { + m_pendingFetchWebsiteDataRequests.append(callbackID); return; } - // Ask the plug-in process for the sites with data. m_connection->send(Messages::PluginProcess::GetSitesWithData(callbackID), 0); } -void PluginProcessProxy::clearSiteData(WebPluginSiteDataManager* webPluginSiteDataManager, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID) +void PluginProcessProxy::deleteWebsiteData(std::chrono::system_clock::time_point modifiedSince, std::function<void ()> completionHandler) { - ASSERT(!m_pendingClearSiteDataReplies.contains(callbackID)); - m_pendingClearSiteDataReplies.set(callbackID, webPluginSiteDataManager); - - if (isLaunching()) { - ClearSiteDataRequest request; - request.sites = sites; - request.flags = flags; - request.maxAgeInSeconds = maxAgeInSeconds; - request.callbackID = callbackID; - m_pendingClearSiteDataRequests.append(request); + uint64_t callbackID = generateCallbackID(); + m_pendingDeleteWebsiteDataCallbacks.set(callbackID, WTFMove(completionHandler)); + + if (state() == State::Launching) { + m_pendingDeleteWebsiteDataRequests.append({ modifiedSince, callbackID }); return; } - // Ask the plug-in process to clear the site data. - m_connection->send(Messages::PluginProcess::ClearSiteData(sites, flags, maxAgeInSeconds, callbackID), 0); + m_connection->send(Messages::PluginProcess::DeleteWebsiteData(modifiedSince, callbackID), 0); +} + +void PluginProcessProxy::deleteWebsiteDataForHostNames(const Vector<String>& hostNames, std::function<void ()> completionHandler) +{ + uint64_t callbackID = generateCallbackID(); + m_pendingDeleteWebsiteDataForHostNamesCallbacks.set(callbackID, WTFMove(completionHandler)); + + if (state() == State::Launching) { + m_pendingDeleteWebsiteDataForHostNamesRequests.append({ hostNames, callbackID }); + return; + } + + m_connection->send(Messages::PluginProcess::DeleteWebsiteDataForHostNames(hostNames, callbackID), 0); } void PluginProcessProxy::pluginProcessCrashedOrFailedToLaunch() @@ -137,28 +154,37 @@ void PluginProcessProxy::pluginProcessCrashedOrFailedToLaunch() while (!m_pendingConnectionReplies.isEmpty()) { RefPtr<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply> reply = m_pendingConnectionReplies.takeFirst(); -#if PLATFORM(MAC) - reply->send(CoreIPC::Attachment(0, MACH_MSG_TYPE_MOVE_SEND), false); -#elif USE(UNIX_DOMAIN_SOCKETS) - reply->send(CoreIPC::Attachment(), false); +#if USE(UNIX_DOMAIN_SOCKETS) + reply->send(IPC::Attachment(), false); +#elif OS(DARWIN) + reply->send(IPC::Attachment(0, MACH_MSG_TYPE_MOVE_SEND), false); #else notImplemented(); #endif } - while (!m_pendingGetSitesReplies.isEmpty()) - didGetSitesWithData(Vector<String>(), m_pendingGetSitesReplies.begin()->key); + m_pendingFetchWebsiteDataRequests.clear(); + for (const auto& callback : m_pendingFetchWebsiteDataCallbacks.values()) + callback({ }); + m_pendingFetchWebsiteDataCallbacks.clear(); + + m_pendingDeleteWebsiteDataRequests.clear(); + for (const auto& callback : m_pendingDeleteWebsiteDataCallbacks.values()) + callback(); + m_pendingDeleteWebsiteDataRequests.clear(); - while (!m_pendingClearSiteDataReplies.isEmpty()) - didClearSiteData(m_pendingClearSiteDataReplies.begin()->key); + m_pendingDeleteWebsiteDataForHostNamesRequests.clear(); + for (const auto& callback : m_pendingDeleteWebsiteDataForHostNamesCallbacks.values()) + callback(); + m_pendingDeleteWebsiteDataForHostNamesCallbacks.clear(); // Tell the plug-in process manager to forget about this plug-in process proxy. This may cause us to be deleted. m_pluginProcessManager->removePluginProcessProxy(this); } -void PluginProcessProxy::didClose(CoreIPC::Connection*) +void PluginProcessProxy::didClose(IPC::Connection&) { -#if PLATFORM(MAC) +#if PLATFORM(COCOA) if (m_modalWindowIsShowing) endModal(); @@ -166,31 +192,31 @@ void PluginProcessProxy::didClose(CoreIPC::Connection*) exitFullscreen(); #endif - const Vector<WebContext*>& contexts = WebContext::allContexts(); - for (size_t i = 0; i < contexts.size(); ++i) - contexts[i]->sendToAllProcesses(Messages::PluginProcessConnectionManager::PluginProcessCrashed(m_pluginProcessToken)); + const Vector<WebProcessPool*>& processPools = WebProcessPool::allProcessPools(); + for (size_t i = 0; i < processPools.size(); ++i) + processPools[i]->sendToAllProcesses(Messages::PluginProcessConnectionManager::PluginProcessCrashed(m_pluginProcessToken)); // This will cause us to be deleted. pluginProcessCrashedOrFailedToLaunch(); } -void PluginProcessProxy::didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::StringReference, CoreIPC::StringReference) +void PluginProcessProxy::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference) { } -void PluginProcessProxy::didFinishLaunching(ProcessLauncher*, CoreIPC::Connection::Identifier connectionIdentifier) +void PluginProcessProxy::didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier connectionIdentifier) { ASSERT(!m_connection); - if (CoreIPC::Connection::identifierIsNull(connectionIdentifier)) { + if (IPC::Connection::identifierIsNull(connectionIdentifier)) { pluginProcessCrashedOrFailedToLaunch(); return; } - m_connection = CoreIPC::Connection::createServerConnection(connectionIdentifier, this, RunLoop::main()); -#if PLATFORM(MAC) + m_connection = IPC::Connection::createServerConnection(connectionIdentifier, *this); +#if (PLATFORM(MAC) || PLATFORM(QT) && USE(MACH_PORTS)) && __MAC_OS_X_VERSION_MIN_REQUIRED <= 101000 m_connection->setShouldCloseConnectionOnMachExceptions(); -#elif PLATFORM(QT) +#elif PLATFORM(QT) && USE(UNIX_DOMAIN_SOCKETS) m_connection->setShouldCloseConnectionOnProcessTermination(processIdentifier()); #endif @@ -210,39 +236,44 @@ void PluginProcessProxy::didFinishLaunching(ProcessLauncher*, CoreIPC::Connectio // Initialize the plug-in host process. m_connection->send(Messages::PluginProcess::InitializePluginProcess(parameters), 0); - // Send all our pending requests. - for (size_t i = 0; i < m_pendingGetSitesRequests.size(); ++i) - m_connection->send(Messages::PluginProcess::GetSitesWithData(m_pendingGetSitesRequests[i]), 0); - m_pendingGetSitesRequests.clear(); +#if PLATFORM(COCOA) + m_connection->send(Messages::PluginProcess::SetQOS(pluginProcessLatencyQOS(), pluginProcessThroughputQOS()), 0); +#endif + + for (auto callbackID : m_pendingFetchWebsiteDataRequests) + m_connection->send(Messages::PluginProcess::GetSitesWithData(callbackID), 0); + m_pendingFetchWebsiteDataRequests.clear(); - for (size_t i = 0; i < m_pendingClearSiteDataRequests.size(); ++i) { - const ClearSiteDataRequest& request = m_pendingClearSiteDataRequests[i]; - m_connection->send(Messages::PluginProcess::ClearSiteData(request.sites, request.flags, request.maxAgeInSeconds, request.callbackID), 0); - } - m_pendingClearSiteDataRequests.clear(); + for (auto& request : m_pendingDeleteWebsiteDataRequests) + m_connection->send(Messages::PluginProcess::DeleteWebsiteData(request.modifiedSince, request.callbackID), 0); + m_pendingDeleteWebsiteDataRequests.clear(); + + for (auto& request : m_pendingDeleteWebsiteDataForHostNamesRequests) + m_connection->send(Messages::PluginProcess::DeleteWebsiteDataForHostNames(request.hostNames, request.callbackID), 0); + m_pendingDeleteWebsiteDataForHostNamesRequests.clear(); for (unsigned i = 0; i < m_numPendingConnectionRequests; ++i) m_connection->send(Messages::PluginProcess::CreateWebProcessConnection(), 0); m_numPendingConnectionRequests = 0; -#if PLATFORM(MAC) - if (WebContext::canEnableProcessSuppressionForGlobalChildProcesses()) +#if PLATFORM(COCOA) + if (!PluginProcessManager::singleton().processSuppressionDisabled()) setProcessSuppressionEnabled(true); #endif } -void PluginProcessProxy::didCreateWebProcessConnection(const CoreIPC::Attachment& connectionIdentifier, bool supportsAsynchronousPluginInitialization) +void PluginProcessProxy::didCreateWebProcessConnection(const IPC::Attachment& connectionIdentifier, bool supportsAsynchronousPluginInitialization) { ASSERT(!m_pendingConnectionReplies.isEmpty()); // Grab the first pending connection reply. RefPtr<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply> reply = m_pendingConnectionReplies.takeFirst(); -#if PLATFORM(MAC) - reply->send(CoreIPC::Attachment(connectionIdentifier.port(), MACH_MSG_TYPE_MOVE_SEND), supportsAsynchronousPluginInitialization); -#elif USE(UNIX_DOMAIN_SOCKETS) +#if USE(UNIX_DOMAIN_SOCKETS) reply->send(connectionIdentifier, supportsAsynchronousPluginInitialization); +#elif OS(DARWIN) + reply->send(IPC::Attachment(connectionIdentifier.port(), MACH_MSG_TYPE_MOVE_SEND), supportsAsynchronousPluginInitialization); #else notImplemented(); #endif @@ -250,20 +281,22 @@ void PluginProcessProxy::didCreateWebProcessConnection(const CoreIPC::Attachment void PluginProcessProxy::didGetSitesWithData(const Vector<String>& sites, uint64_t callbackID) { - RefPtr<WebPluginSiteDataManager> webPluginSiteDataManager = m_pendingGetSitesReplies.take(callbackID); - ASSERT(webPluginSiteDataManager); + auto callback = m_pendingFetchWebsiteDataCallbacks.take(callbackID); + callback(sites); +} - webPluginSiteDataManager->didGetSitesWithDataForSinglePlugin(sites, callbackID); +void PluginProcessProxy::didDeleteWebsiteData(uint64_t callbackID) +{ + auto callback = m_pendingDeleteWebsiteDataCallbacks.take(callbackID); + callback(); } -void PluginProcessProxy::didClearSiteData(uint64_t callbackID) +void PluginProcessProxy::didDeleteWebsiteDataForHostNames(uint64_t callbackID) { - RefPtr<WebPluginSiteDataManager> webPluginSiteDataManager = m_pendingClearSiteDataReplies.take(callbackID); - ASSERT(webPluginSiteDataManager); - - webPluginSiteDataManager->didClearSiteDataForSinglePlugin(callbackID); + auto callback = m_pendingDeleteWebsiteDataForHostNamesCallbacks.take(callbackID); + callback(); } } // namespace WebKit -#endif // ENABLE(PLUGIN_PROCESS) +#endif // ENABLE(NETSCAPE_PLUGIN_API) diff --git a/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.h b/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.h index a76cba196..b43b78353 100644 --- a/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.h +++ b/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.h @@ -26,7 +26,7 @@ #ifndef PluginProcessProxy_h #define PluginProcessProxy_h -#if ENABLE(PLUGIN_PROCESS) +#if ENABLE(NETSCAPE_PLUGIN_API) #include "ChildProcessProxy.h" #include "Connection.h" @@ -37,21 +37,15 @@ #include "WebProcessProxyMessages.h" #include <wtf/Deque.h> -#if PLATFORM(MAC) +#if PLATFORM(COCOA) #include <wtf/RetainPtr.h> OBJC_CLASS NSObject; OBJC_CLASS WKPlaceholderModalWindow; #endif -// FIXME: This is platform specific. -namespace CoreIPC { - class MachPort; -} - namespace WebKit { class PluginProcessManager; -class WebPluginSiteDataManager; class WebProcessProxy; struct PluginProcessCreationParameters; @@ -60,12 +54,21 @@ struct RawPluginMetaData { String name; String description; String mimeDescription; + +#if PLATFORM(GTK) + bool requiresGtk2; +#endif }; #endif +#if PLATFORM(COCOA) +int pluginProcessLatencyQOS(); +int pluginProcessThroughputQOS(); +#endif + class PluginProcessProxy : public ChildProcessProxy { public: - static PassRefPtr<PluginProcessProxy> create(PluginProcessManager*, const PluginProcessAttributes&, uint64_t pluginProcessToken); + static Ref<PluginProcessProxy> create(PluginProcessManager*, const PluginProcessAttributes&, uint64_t pluginProcessToken); ~PluginProcessProxy(); const PluginProcessAttributes& pluginProcessAttributes() const { return m_pluginProcessAttributes; } @@ -74,25 +77,23 @@ public: // Asks the plug-in process to create a new connection to a web process. The connection identifier will be // encoded in the given argument encoder and sent back to the connection of the given web process. void getPluginProcessConnection(PassRefPtr<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply>); - - // Asks the plug-in process to get a list of domains for which the plug-in has data stored. - void getSitesWithData(WebPluginSiteDataManager*, uint64_t callbackID); - // Asks the plug-in process to clear the data for the given sites. - void clearSiteData(WebPluginSiteDataManager*, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID); + void fetchWebsiteData(std::function<void (Vector<String>)> completionHandler); + void deleteWebsiteData(std::chrono::system_clock::time_point modifiedSince, std::function<void ()> completionHandler); + void deleteWebsiteDataForHostNames(const Vector<String>& hostNames, std::function<void ()> completionHandler); bool isValid() const { return m_connection; } -#if PLATFORM(MAC) +#if PLATFORM(COCOA) void setProcessSuppressionEnabled(bool); - // Returns whether the plug-in needs the heap to be marked executable. - static bool pluginNeedsExecutableHeap(const PluginModuleInfo&); - +#if __MAC_OS_X_VERSION_MIN_REQUIRED <= 101000 // Creates a property list in ~/Library/Preferences that contains all the MIME types supported by the plug-in. static bool createPropertyListFile(const PluginModuleInfo&); #endif +#endif + #if PLUGIN_ARCHITECTURE(X11) static bool scanPlugin(const String& pluginPath, RawPluginMetaData& result); #endif @@ -100,27 +101,31 @@ public: private: PluginProcessProxy(PluginProcessManager*, const PluginProcessAttributes&, uint64_t pluginProcessToken); - virtual void getLaunchOptions(ProcessLauncher::LaunchOptions&) OVERRIDE; + virtual void getLaunchOptions(ProcessLauncher::LaunchOptions&) override; void platformGetLaunchOptions(ProcessLauncher::LaunchOptions&, const PluginProcessAttributes&); + virtual void processWillShutDown(IPC::Connection&) override; void pluginProcessCrashedOrFailedToLaunch(); - // CoreIPC::Connection::Client - virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&) OVERRIDE; - virtual void didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&, OwnPtr<CoreIPC::MessageEncoder>&) OVERRIDE; + // IPC::Connection::Client + virtual void didReceiveMessage(IPC::Connection&, IPC::MessageDecoder&) override; + virtual void didReceiveSyncMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr<IPC::MessageEncoder>&) override; - virtual void didClose(CoreIPC::Connection*) OVERRIDE; - virtual void didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::StringReference messageReceiverName, CoreIPC::StringReference messageName) OVERRIDE; + virtual void didClose(IPC::Connection&) override; + virtual void didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference messageReceiverName, IPC::StringReference messageName) override; + virtual IPC::ProcessType localProcessType() override { return IPC::ProcessType::UI; } + virtual IPC::ProcessType remoteProcessType() override { return IPC::ProcessType::Plugin; } // ProcessLauncher::Client - virtual void didFinishLaunching(ProcessLauncher*, CoreIPC::Connection::Identifier); + virtual void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier) override; // Message handlers - void didCreateWebProcessConnection(const CoreIPC::Attachment&, bool supportsAsynchronousPluginInitialization); + void didCreateWebProcessConnection(const IPC::Attachment&, bool supportsAsynchronousPluginInitialization); void didGetSitesWithData(const Vector<String>& sites, uint64_t callbackID); - void didClearSiteData(uint64_t callbackID); + void didDeleteWebsiteData(uint64_t callbackID); + void didDeleteWebsiteDataForHostNames(uint64_t callbackID); -#if PLATFORM(MAC) +#if PLATFORM(COCOA) bool getPluginProcessSerialNumber(ProcessSerialNumber&); void makePluginProcessTheFrontProcess(); void makeUIProcessTheFrontProcess(); @@ -134,10 +139,10 @@ private: void endModal(); void applicationDidBecomeActive(); - void openPluginPreferencePane(); void launchProcess(const String& launchPath, const Vector<String>& arguments, bool& result); void launchApplicationAtURL(const String& urlString, const Vector<String>& arguments, bool& result); void openURL(const String& url, bool& result, int32_t& status, String& launchedURLString); + void openFile(const String& fullPath, bool& result); #endif void platformInitializePluginProcess(PluginProcessCreationParameters& parameters); @@ -149,27 +154,32 @@ private: uint64_t m_pluginProcessToken; // The connection to the plug-in host process. - RefPtr<CoreIPC::Connection> m_connection; + RefPtr<IPC::Connection> m_connection; + + Deque<RefPtr<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply>> m_pendingConnectionReplies; - Deque<RefPtr<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply> > m_pendingConnectionReplies; + Vector<uint64_t> m_pendingFetchWebsiteDataRequests; + HashMap<uint64_t, std::function<void (Vector<String>)>> m_pendingFetchWebsiteDataCallbacks; - Vector<uint64_t> m_pendingGetSitesRequests; - HashMap<uint64_t, RefPtr<WebPluginSiteDataManager> > m_pendingGetSitesReplies; + struct DeleteWebsiteDataRequest { + std::chrono::system_clock::time_point modifiedSince; + uint64_t callbackID; + }; + Vector<DeleteWebsiteDataRequest> m_pendingDeleteWebsiteDataRequests; + HashMap<uint64_t, std::function<void ()>> m_pendingDeleteWebsiteDataCallbacks; - struct ClearSiteDataRequest { - Vector<String> sites; - uint64_t flags; - uint64_t maxAgeInSeconds; + struct DeleteWebsiteDataForHostNamesRequest { + Vector<String> hostNames; uint64_t callbackID; }; - Vector<ClearSiteDataRequest> m_pendingClearSiteDataRequests; - HashMap<uint64_t, RefPtr<WebPluginSiteDataManager> > m_pendingClearSiteDataReplies; + Vector<DeleteWebsiteDataForHostNamesRequest> m_pendingDeleteWebsiteDataForHostNamesRequests; + HashMap<uint64_t, std::function<void ()>> m_pendingDeleteWebsiteDataForHostNamesCallbacks; // If createPluginConnection is called while the process is still launching we'll keep count of it and send a bunch of requests // when the process finishes launching. unsigned m_numPendingConnectionRequests; -#if PLATFORM(MAC) +#if PLATFORM(COCOA) RetainPtr<NSObject> m_activationObserver; RetainPtr<WKPlaceholderModalWindow *> m_placeholderWindow; bool m_modalWindowIsShowing; @@ -180,6 +190,6 @@ private: } // namespace WebKit -#endif // ENABLE(PLUGIN_PROCESS) +#endif // ENABLE(NETSCAPE_PLUGIN_API) #endif // PluginProcessProxy_h diff --git a/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.messages.in b/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.messages.in index aa3b106c5..e18e55eb0 100644 --- a/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.messages.in +++ b/Source/WebKit2/UIProcess/Plugins/PluginProcessProxy.messages.in @@ -20,29 +20,30 @@ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#if ENABLE(PLUGIN_PROCESS) +#if ENABLE(NETSCAPE_PLUGIN_API) messages -> PluginProcessProxy { - DidCreateWebProcessConnection(CoreIPC::Attachment connectionIdentifier, bool supportsAsynchronousPluginInitialization) + DidCreateWebProcessConnection(IPC::Attachment connectionIdentifier, bool supportsAsynchronousPluginInitialization) - DidGetSitesWithData(Vector<WTF::String> sites, uint64_t callbackID) - DidClearSiteData(uint64_t callbackID) + DidGetSitesWithData(Vector<String> sites, uint64_t callbackID) + DidDeleteWebsiteData(uint64_t callbackID) + DidDeleteWebsiteDataForHostNames(uint64_t callbackID) -#if PLATFORM(MAC) +#if PLATFORM(COCOA) SetModalWindowIsShowing(bool modalWindowIsShowing) SetFullscreenWindowIsShowing(bool fullscreenWindowIsShowing) - # Open the plug-ins preference pane (as specified in the plug-in's Info.plist file). - OpenPluginPreferencePane() - # Returns true if the UI process launched the process. - LaunchProcess(WTF::String launchPath, Vector<WTF::String> arguments) -> (bool result) + LaunchProcess(String launchPath, Vector<String> arguments) -> (bool result) # Returns true if the UI process launched the application. - LaunchApplicationAtURL(WTF::String url, Vector<WTF::String> arguments) -> (bool result) + LaunchApplicationAtURL(String url, Vector<String> arguments) -> (bool result) # Returns true if the UI process did open the URL. - OpenURL(WTF::String urlString) -> (bool result, int32_t status, WTF::String launchedURLString) + OpenURL(String urlString) -> (bool result, int32_t status, String launchedURLString) + + # Returns true if the UI process did open the file. + OpenFile(String fullPath) -> (bool result) #endif } diff --git a/Source/WebKit2/UIProcess/Plugins/WebPluginSiteDataManager.cpp b/Source/WebKit2/UIProcess/Plugins/WebPluginSiteDataManager.cpp deleted file mode 100644 index 1ea01a088..000000000 --- a/Source/WebKit2/UIProcess/Plugins/WebPluginSiteDataManager.cpp +++ /dev/null @@ -1,294 +0,0 @@ -/* - * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WebPluginSiteDataManager.h" - -#if ENABLE(NETSCAPE_PLUGIN_API) - -#include "ImmutableArray.h" -#include "PluginProcessManager.h" -#include "WebContext.h" -#include "WebProcessMessages.h" - -using namespace WebCore; - -namespace WebKit { - -#if ENABLE(PLUGIN_PROCESS) -class WebPluginSiteDataManager::GetSitesWithDataState { -public: - explicit GetSitesWithDataState(WebPluginSiteDataManager* webPluginSiteDataManager, uint64_t callbackID) - : m_webPluginSiteDataManager(webPluginSiteDataManager) - , m_callbackID(callbackID) - , m_plugins(webPluginSiteDataManager->m_webContext->pluginInfoStore().plugins()) - { - } - - void getSitesWithDataForNextPlugin() - { - if (m_plugins.isEmpty()) { - Vector<String> sites; - copyToVector(m_sites, sites); - - m_webPluginSiteDataManager->didGetSitesWithDataForAllPlugins(sites, m_callbackID); - return; - } - - PluginProcessManager::shared().getSitesWithData(m_plugins.last(), m_webPluginSiteDataManager, m_callbackID); - m_plugins.removeLast(); - } - - void didGetSitesWithDataForSinglePlugin(const Vector<String>& sites) - { - for (size_t i = 0; i < sites.size(); ++i) - m_sites.add(sites[i]); - - getSitesWithDataForNextPlugin(); - } - -private: - WebPluginSiteDataManager* m_webPluginSiteDataManager; - uint64_t m_callbackID; - Vector<PluginModuleInfo> m_plugins; - HashSet<String> m_sites; -}; - -class WebPluginSiteDataManager::ClearSiteDataState { -public: - explicit ClearSiteDataState(WebPluginSiteDataManager* webPluginSiteDataManager, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID) - : m_webPluginSiteDataManager(webPluginSiteDataManager) - , m_sites(sites) - , m_flags(flags) - , m_maxAgeInSeconds(maxAgeInSeconds) - , m_callbackID(callbackID) - , m_plugins(webPluginSiteDataManager->m_webContext->pluginInfoStore().plugins()) - { - } - - void clearSiteDataForNextPlugin() - { - if (m_plugins.isEmpty()) { - m_webPluginSiteDataManager->didClearSiteDataForAllPlugins(m_callbackID); - return; - } - - PluginProcessManager::shared().clearSiteData(m_plugins.last(), m_webPluginSiteDataManager, m_sites, m_flags, m_maxAgeInSeconds, m_callbackID); - m_plugins.removeLast(); - } - - void didClearSiteDataForSinglePlugin() - { - clearSiteDataForNextPlugin(); - } - -private: - WebPluginSiteDataManager* m_webPluginSiteDataManager; - Vector<String> m_sites; - uint64_t m_flags; - uint64_t m_maxAgeInSeconds; - uint64_t m_callbackID; - Vector<PluginModuleInfo> m_plugins; -}; -#endif // ENABLE(PLUGIN_PROCESS) - -PassRefPtr<WebPluginSiteDataManager> WebPluginSiteDataManager::create(WebContext* webContext) -{ - return adoptRef(new WebPluginSiteDataManager(webContext)); -} - -WebPluginSiteDataManager::WebPluginSiteDataManager(WebContext* webContext) - : m_webContext(webContext) -{ -} - -WebPluginSiteDataManager::~WebPluginSiteDataManager() -{ - ASSERT(m_arrayCallbacks.isEmpty()); - ASSERT(m_voidCallbacks.isEmpty()); -#if ENABLE(PLUGIN_PROCESS) - ASSERT(m_pendingGetSitesWithData.isEmpty()); - ASSERT(m_pendingClearSiteData.isEmpty()); -#endif -} - -void WebPluginSiteDataManager::invalidate() -{ - invalidateCallbackMap(m_arrayCallbacks); - -#if ENABLE(PLUGIN_PROCESS) - m_pendingGetSitesWithData.clear(); - m_pendingClearSiteData.clear(); -#endif -} - -void WebPluginSiteDataManager::getSitesWithData(PassRefPtr<ArrayCallback> prpCallback) -{ - RefPtr<ArrayCallback> callback = prpCallback; - - if (!m_webContext) { - callback->invalidate(); - return; - } - - uint64_t callbackID = callback->callbackID(); - m_arrayCallbacks.set(callbackID, callback.release()); - -#if ENABLE(PLUGIN_PROCESS) - ASSERT(!m_pendingGetSitesWithData.contains(callbackID)); - - GetSitesWithDataState* state = new GetSitesWithDataState(this, callbackID); - m_pendingGetSitesWithData.set(callbackID, adoptPtr(state)); - state->getSitesWithDataForNextPlugin(); -#else - Vector<PluginModuleInfo> plugins = m_webContext->pluginInfoStore().plugins(); - Vector<String> pluginPaths; - for (size_t i = 0; i < plugins.size(); ++i) - pluginPaths.append(plugins[i].path); - - ASSERT(m_webContext->processModel() == ProcessModelSharedSecondaryProcess); // Plugin process is required for multiple WebProcess mode. - m_webContext->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebProcess::GetSitesWithPluginData(pluginPaths, callbackID)); -#endif -} - -void WebPluginSiteDataManager::didGetSitesWithData(const Vector<String>& sites, uint64_t callbackID) -{ - RefPtr<ArrayCallback> callback = m_arrayCallbacks.take(callbackID); - if (!callback) { - // FIXME: Log error or assert. - return; - } - - Vector<RefPtr<APIObject> > sitesWK(sites.size()); - - for (size_t i = 0; i < sites.size(); ++i) - sitesWK[i] = WebString::create(sites[i]); - - RefPtr<ImmutableArray> resultArray = ImmutableArray::adopt(sitesWK); - callback->performCallbackWithReturnValue(resultArray.get()); -} - -void WebPluginSiteDataManager::clearSiteData(ImmutableArray* sites, uint64_t flags, uint64_t maxAgeInSeconds, PassRefPtr<VoidCallback> prpCallback) -{ - RefPtr<VoidCallback> callback = prpCallback; - if (!m_webContext) { - callback->invalidate(); - return; - } - - Vector<String> sitesVector; - - // If the array is empty, don't do anything. - if (sites) { - if (!sites->size()) { - callback->performCallback(); - return; - } - - for (size_t i = 0; i < sites->size(); ++i) { - if (WebString* site = sites->at<WebString>(i)) - sitesVector.append(site->string()); - } - } - - uint64_t callbackID = callback->callbackID(); - m_voidCallbacks.set(callbackID, callback.release()); - -#if ENABLE(PLUGIN_PROCESS) - ASSERT(!m_pendingClearSiteData.contains(callbackID)); - - ClearSiteDataState* state = new ClearSiteDataState(this, sitesVector, flags, maxAgeInSeconds, callbackID); - m_pendingClearSiteData.set(callbackID, adoptPtr(state)); - state->clearSiteDataForNextPlugin(); -#else - Vector<PluginModuleInfo> plugins = m_webContext->pluginInfoStore().plugins(); - Vector<String> pluginPaths; - for (size_t i = 0; i < plugins.size(); ++i) - pluginPaths.append(plugins[i].path); - - ASSERT(m_webContext->processModel() == ProcessModelSharedSecondaryProcess); // Plugin process is required for multiple WebProcess mode. - m_webContext->sendToAllProcessesRelaunchingThemIfNecessary(Messages::WebProcess::ClearPluginSiteData(pluginPaths, sitesVector, flags, maxAgeInSeconds, callbackID)); -#endif -} - -void WebPluginSiteDataManager::didClearSiteData(uint64_t callbackID) -{ - RefPtr<VoidCallback> callback = m_voidCallbacks.take(callbackID); - if (!callback) { - // FIXME: Log error or assert. - return; - } - - callback->performCallback(); -} - -bool WebPluginSiteDataManager::shouldTerminate(WebProcessProxy*) const -{ -#if ENABLE(PLUGIN_PROCESS) - // When out of process plug-ins are enabled, the web process is not involved in fetching site data. - return true; -#else - return m_arrayCallbacks.isEmpty() && m_voidCallbacks.isEmpty(); -#endif -} - -#if ENABLE(PLUGIN_PROCESS) -void WebPluginSiteDataManager::didGetSitesWithDataForSinglePlugin(const Vector<String>& sites, uint64_t callbackID) -{ - GetSitesWithDataState* state = m_pendingGetSitesWithData.get(callbackID); - ASSERT(state); - - state->didGetSitesWithDataForSinglePlugin(sites); -} - -void WebPluginSiteDataManager::didGetSitesWithDataForAllPlugins(const Vector<String>& sites, uint64_t callbackID) -{ - OwnPtr<GetSitesWithDataState> state = m_pendingGetSitesWithData.take(callbackID); - ASSERT(state); - - didGetSitesWithData(sites, callbackID); -} - -void WebPluginSiteDataManager::didClearSiteDataForSinglePlugin(uint64_t callbackID) -{ - ClearSiteDataState* state = m_pendingClearSiteData.get(callbackID); - ASSERT(state); - - state->didClearSiteDataForSinglePlugin(); -} - -void WebPluginSiteDataManager::didClearSiteDataForAllPlugins(uint64_t callbackID) -{ - OwnPtr<ClearSiteDataState> state = m_pendingClearSiteData.take(callbackID); - ASSERT(state); - - didClearSiteData(callbackID); -} - -#endif - -} // namespace WebKit - -#endif // ENABLE(NETSCAPE_PLUGIN_API) diff --git a/Source/WebKit2/UIProcess/Plugins/WebPluginSiteDataManager.h b/Source/WebKit2/UIProcess/Plugins/WebPluginSiteDataManager.h deleted file mode 100644 index c770f132b..000000000 --- a/Source/WebKit2/UIProcess/Plugins/WebPluginSiteDataManager.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2011, 2012 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WebPluginSiteDataManager_h -#define WebPluginSiteDataManager_h - -#if ENABLE(NETSCAPE_PLUGIN_API) - -#include "APIObject.h" -#include "Arguments.h" -#include "GenericCallback.h" -#include <wtf/HashMap.h> -#include <wtf/PassRefPtr.h> - -namespace WebKit { - -class WebContext; -class WebProcessProxy; - -typedef GenericCallback<WKArrayRef> ArrayCallback; - -class WebPluginSiteDataManager : public TypedAPIObject<APIObject::TypePluginSiteDataManager> { -public: - static PassRefPtr<WebPluginSiteDataManager> create(WebContext*); - virtual ~WebPluginSiteDataManager(); - - void invalidate(); - void clearContext() { m_webContext = 0; } - - void getSitesWithData(PassRefPtr<ArrayCallback>); - void didGetSitesWithData(const Vector<String>& sites, uint64_t callbackID); - - void clearSiteData(ImmutableArray* sites, uint64_t flags, uint64_t maxAgeInSeconds, PassRefPtr<VoidCallback>); - void didClearSiteData(uint64_t callbackID); - -#if ENABLE(PLUGIN_PROCESS) - void didGetSitesWithDataForSinglePlugin(const Vector<String>& sites, uint64_t callbackID); - void didClearSiteDataForSinglePlugin(uint64_t callbackID); -#endif - - bool shouldTerminate(WebProcessProxy*) const; - -private: - explicit WebPluginSiteDataManager(WebContext*); - - WebContext* m_webContext; - HashMap<uint64_t, RefPtr<ArrayCallback> > m_arrayCallbacks; - HashMap<uint64_t, RefPtr<VoidCallback> > m_voidCallbacks; - -#if ENABLE(PLUGIN_PROCESS) - void didGetSitesWithDataForAllPlugins(const Vector<String>& sites, uint64_t callbackID); - void didClearSiteDataForAllPlugins(uint64_t callbackID); - - class GetSitesWithDataState; - HashMap<uint64_t, OwnPtr<GetSitesWithDataState> > m_pendingGetSitesWithData; - - class ClearSiteDataState; - HashMap<uint64_t, OwnPtr<ClearSiteDataState> > m_pendingClearSiteData; -#endif -}; - -} // namespace WebKit - -#endif // ENABLE(NETSCAPE_PLUGIN_API) - -#endif // WebPluginSiteDataManager_h diff --git a/Source/WebKit2/UIProcess/Plugins/mac/PluginInfoStoreMac.mm b/Source/WebKit2/UIProcess/Plugins/mac/PluginInfoStoreMac.mm deleted file mode 100644 index 61367c51b..000000000 --- a/Source/WebKit2/UIProcess/Plugins/mac/PluginInfoStoreMac.mm +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2010, 2012 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "config.h" -#import "PluginInfoStore.h" - -#if ENABLE(NETSCAPE_PLUGIN_API) - -#import "NetscapePluginModule.h" -#import "WebKitSystemInterface.h" -#import <WebCore/WebCoreNSStringExtras.h> -#import <wtf/HashSet.h> -#import <wtf/RetainPtr.h> - -using namespace WebCore; - -static const char* const oracleJavaAppletPluginBundleIdentifier = "com.oracle.java.JavaAppletPlugin"; - -namespace WebKit { - -Vector<String> PluginInfoStore::pluginsDirectories() -{ - Vector<String> pluginsDirectories; - - pluginsDirectories.append([NSHomeDirectory() stringByAppendingPathComponent:@"Library/Internet Plug-Ins"]); - pluginsDirectories.append("/Library/Internet Plug-Ins"); - - return pluginsDirectories; -} - -// FIXME: Once the UI process knows the difference between the main thread and the web thread we can drop this and just use -// String::createCFString. -static CFStringRef safeCreateCFString(const String& string) -{ - return CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar*>(string.characters()), string.length()); -} - -Vector<String> PluginInfoStore::pluginPathsInDirectory(const String& directory) -{ - Vector<String> pluginPaths; - - RetainPtr<CFStringRef> directoryCFString = adoptCF(safeCreateCFString(directory)); - - NSArray *filenames = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:(NSString *)directoryCFString.get() error:nil]; - for (NSString *filename in filenames) - pluginPaths.append([(NSString *)directoryCFString.get() stringByAppendingPathComponent:filename]); - - return pluginPaths; -} - -Vector<String> PluginInfoStore::individualPluginPaths() -{ - return Vector<String>(); -} - -bool PluginInfoStore::getPluginInfo(const String& pluginPath, PluginModuleInfo& plugin) -{ - return NetscapePluginModule::getPluginInfo(pluginPath, plugin); -} - -static size_t findPluginWithBundleIdentifier(const Vector<PluginModuleInfo>& plugins, const String& bundleIdentifier) -{ - for (size_t i = 0; i < plugins.size(); ++i) { - if (plugins[i].bundleIdentifier == bundleIdentifier) - return i; - } - - return notFound; -} - -// Returns true if the given plug-in should be loaded, false otherwise. -static bool checkForPreferredPlugin(Vector<PluginModuleInfo>& alreadyLoadedPlugins, const PluginModuleInfo& plugin, const String& oldPluginBundleIdentifier, const String& newPluginBundleIdentifier) -{ - if (plugin.bundleIdentifier == oldPluginBundleIdentifier) { - // If we've already found the new plug-in, we don't want to load the old plug-in. - if (findPluginWithBundleIdentifier(alreadyLoadedPlugins, newPluginBundleIdentifier) != notFound) - return false; - } else if (plugin.bundleIdentifier == newPluginBundleIdentifier) { - // If we've already found the old plug-in, remove it from the list of loaded plug-ins. - size_t oldPluginIndex = findPluginWithBundleIdentifier(alreadyLoadedPlugins, oldPluginBundleIdentifier); - if (oldPluginIndex != notFound) - alreadyLoadedPlugins.remove(oldPluginIndex); - } - - return true; -} - -static bool shouldBlockPlugin(const PluginModuleInfo& plugin) -{ - return PluginInfoStore::defaultLoadPolicyForPlugin(plugin) == PluginModuleBlocked; -} - -bool PluginInfoStore::shouldUsePlugin(Vector<PluginModuleInfo>& alreadyLoadedPlugins, const PluginModuleInfo& plugin) -{ - for (size_t i = 0; i < alreadyLoadedPlugins.size(); ++i) { - const PluginModuleInfo& loadedPlugin = alreadyLoadedPlugins[i]; - - // If a plug-in with the same bundle identifier already exists, we don't want to load it. - // However, if the already existing plug-in is blocked we want to replace it with the new plug-in. - if (loadedPlugin.bundleIdentifier == plugin.bundleIdentifier) { - if (!shouldBlockPlugin(loadedPlugin)) - return false; - - alreadyLoadedPlugins.remove(i); - break; - } - } - - // Prefer the Oracle Java plug-in over the Apple java plug-in. - if (!checkForPreferredPlugin(alreadyLoadedPlugins, plugin, "com.apple.java.JavaAppletPlugin", oracleJavaAppletPluginBundleIdentifier)) - return false; - - return true; -} - -PluginModuleLoadPolicy PluginInfoStore::defaultLoadPolicyForPlugin(const PluginModuleInfo& plugin) -{ - if (WKShouldBlockPlugin(plugin.bundleIdentifier, plugin.versionString)) - return PluginModuleBlocked; - - return PluginModuleLoadNormally; -} - -String PluginInfoStore::getMIMETypeForExtension(const String& extension) -{ - // FIXME: This should just call MIMETypeRegistry::getMIMETypeForExtension and be - // strength reduced into the callsite once we can safely convert String - // to CFStringRef off the main thread. - - RetainPtr<CFStringRef> extensionCFString = adoptCF(safeCreateCFString(extension)); - return WKGetMIMETypeForExtension((NSString *)extensionCFString.get()); -} - -PluginModuleInfo PluginInfoStore::findPluginWithBundleIdentifier(const String& bundleIdentifier) -{ - loadPluginsIfNecessary(); - - for (size_t i = 0; i < m_plugins.size(); ++i) { - if (m_plugins[i].bundleIdentifier == bundleIdentifier) - return m_plugins[i]; - } - - return PluginModuleInfo(); -} - -} // namespace WebKit - -#endif // ENABLE(NETSCAPE_PLUGIN_API) diff --git a/Source/WebKit2/UIProcess/Plugins/mac/PluginProcessManagerMac.mm b/Source/WebKit2/UIProcess/Plugins/mac/PluginProcessManagerMac.mm deleted file mode 100644 index 771cf7801..000000000 --- a/Source/WebKit2/UIProcess/Plugins/mac/PluginProcessManagerMac.mm +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2012 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "config.h" -#import "PluginProcessManager.h" - -#if ENABLE(PLUGIN_PROCESS) - -#import "PluginProcessProxy.h" - -namespace WebKit { - -void PluginProcessManager::setProcessSuppressionEnabled(bool processSuppressionEnabled) -{ - size_t processCount = m_pluginProcesses.size(); - for (size_t i = 0; i < processCount; ++i) - m_pluginProcesses[i]->setProcessSuppressionEnabled(processSuppressionEnabled); -} - -} // namespace WebKit - -#endif // ENABLE(PLUGIN_PROCESS) diff --git a/Source/WebKit2/UIProcess/Plugins/mac/PluginProcessProxyMac.mm b/Source/WebKit2/UIProcess/Plugins/mac/PluginProcessProxyMac.mm deleted file mode 100644 index 4ce88b3d2..000000000 --- a/Source/WebKit2/UIProcess/Plugins/mac/PluginProcessProxyMac.mm +++ /dev/null @@ -1,477 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "config.h" -#import "PluginProcessProxy.h" - -#if ENABLE(PLUGIN_PROCESS) - -#import "DynamicLinkerEnvironmentExtractor.h" -#import "EnvironmentVariables.h" -#import "PluginProcessCreationParameters.h" -#import "PluginProcessMessages.h" -#import "WebKitSystemInterface.h" -#import <WebCore/FileSystem.h> -#import <WebCore/KURL.h> -#import <WebCore/RuntimeApplicationChecks.h> -#import <crt_externs.h> -#import <mach-o/dyld.h> -#import <spawn.h> -#import <wtf/text/CString.h> - -#import <QuartzCore/CARemoteLayerServer.h> - -@interface WKPlaceholderModalWindow : NSWindow -@end - -@implementation WKPlaceholderModalWindow - -// Prevent NSApp from calling requestUserAttention: when the window is shown -// modally, even if the app is inactive. See 6823049. -- (BOOL)_wantsUserAttention -{ - return NO; -} - -@end - -using namespace WebCore; - -namespace WebKit { - -bool PluginProcessProxy::pluginNeedsExecutableHeap(const PluginModuleInfo& pluginInfo) -{ - static bool forceNonexecutableHeapForPlugins = [[NSUserDefaults standardUserDefaults] boolForKey:@"ForceNonexecutableHeapForPlugins"]; - if (forceNonexecutableHeapForPlugins) - return false; - - if (pluginInfo.bundleIdentifier == "com.apple.QuickTime Plugin.plugin") - return false; - - return true; -} - -bool PluginProcessProxy::createPropertyListFile(const PluginModuleInfo& plugin) -{ - NSBundle *webKit2Bundle = [NSBundle bundleWithIdentifier:@"com.apple.WebKit2"]; - NSString *frameworksPath = [[webKit2Bundle bundlePath] stringByDeletingLastPathComponent]; - const char* frameworkExecutablePath = [[webKit2Bundle executablePath] fileSystemRepresentation]; - - NSString *processPath = [webKit2Bundle pathForAuxiliaryExecutable:@"PluginProcess.app"]; - NSString *processAppExecutablePath = [[NSBundle bundleWithPath:processPath] executablePath]; - - CString pluginPathString = fileSystemRepresentation(plugin.path); - - posix_spawnattr_t attr; - posix_spawnattr_init(&attr); - - cpu_type_t cpuTypes[] = { plugin.pluginArchitecture }; - size_t outCount = 0; - posix_spawnattr_setbinpref_np(&attr, 1, cpuTypes, &outCount); - - EnvironmentVariables environmentVariables; - - DynamicLinkerEnvironmentExtractor environmentExtractor([[NSBundle mainBundle] executablePath], _NSGetMachExecuteHeader()->cputype); - environmentExtractor.getExtractedEnvironmentVariables(environmentVariables); - - // To make engineering builds work, if the path is outside of /System set up - // DYLD_FRAMEWORK_PATH to pick up other frameworks, but don't do it for the - // production configuration because it involves extra file system access. - if (![frameworksPath hasPrefix:@"/System/"]) - environmentVariables.appendValue("DYLD_FRAMEWORK_PATH", [frameworksPath fileSystemRepresentation], ':'); - - const char* args[] = { [processAppExecutablePath fileSystemRepresentation], frameworkExecutablePath, "-type", "pluginprocess", "-createPluginMIMETypesPreferences", pluginPathString.data(), 0 }; - - pid_t pid; - int result = posix_spawn(&pid, args[0], 0, &attr, const_cast<char* const*>(args), environmentVariables.environmentPointer()); - posix_spawnattr_destroy(&attr); - - if (result) - return false; - int status; - if (waitpid(pid, &status, 0) < 0) - return false; - - if (!WIFEXITED(status)) - return false; - - if (WEXITSTATUS(status) != EXIT_SUCCESS) - return false; - - return true; -} - -#if HAVE(XPC) -static bool shouldUseXPC() -{ - if (id value = [[NSUserDefaults standardUserDefaults] objectForKey:@"WebKit2UseXPCServiceForWebProcess"]) - return [value boolValue]; - -#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 - // FIXME: Temporary workaround for <rdar://problem/13236883> - if (applicationIsSafari()) - return false; - - return true; -#else - return false; -#endif -} -#endif - -void PluginProcessProxy::platformGetLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions, const PluginProcessAttributes& pluginProcessAttributes) -{ - launchOptions.architecture = pluginProcessAttributes.moduleInfo.pluginArchitecture; - launchOptions.executableHeap = PluginProcessProxy::pluginNeedsExecutableHeap(pluginProcessAttributes.moduleInfo); - launchOptions.extraInitializationData.add("plugin-path", pluginProcessAttributes.moduleInfo.path); - - // FIXME: Don't allow this if the UI process is sandboxed. - if (pluginProcessAttributes.sandboxPolicy == PluginProcessSandboxPolicyUnsandboxed) - launchOptions.extraInitializationData.add("disable-sandbox", "1"); - -#if HAVE(XPC) - launchOptions.useXPC = shouldUseXPC(); -#endif -} - -void PluginProcessProxy::platformInitializePluginProcess(PluginProcessCreationParameters& parameters) -{ - // For now only Flash is known to behave with asynchronous plug-in initialization. - parameters.supportsAsynchronousPluginInitialization = m_pluginProcessAttributes.moduleInfo.bundleIdentifier == "com.macromedia.Flash Player.plugin"; - -#if USE(ACCELERATED_COMPOSITING) && HAVE(HOSTED_CORE_ANIMATION) - mach_port_t renderServerPort = [[CARemoteLayerServer sharedServer] serverPort]; - if (renderServerPort != MACH_PORT_NULL) - parameters.acceleratedCompositingPort = CoreIPC::MachPort(renderServerPort, MACH_MSG_TYPE_COPY_SEND); -#endif -} - -bool PluginProcessProxy::getPluginProcessSerialNumber(ProcessSerialNumber& pluginProcessSerialNumber) -{ - pid_t pluginProcessPID = processIdentifier(); -#if COMPILER(CLANG) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif - return GetProcessForPID(pluginProcessPID, &pluginProcessSerialNumber) == noErr; -#if COMPILER(CLANG) -#pragma clang diagnostic pop -#endif -} - -void PluginProcessProxy::makePluginProcessTheFrontProcess() -{ - ProcessSerialNumber pluginProcessSerialNumber; - if (!getPluginProcessSerialNumber(pluginProcessSerialNumber)) - return; - -#if COMPILER(CLANG) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif - SetFrontProcess(&pluginProcessSerialNumber); -#if COMPILER(CLANG) -#pragma clang diagnostic pop -#endif -} - -void PluginProcessProxy::makeUIProcessTheFrontProcess() -{ - ProcessSerialNumber processSerialNumber; -#if COMPILER(CLANG) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif - GetCurrentProcess(&processSerialNumber); - SetFrontProcess(&processSerialNumber); -#if COMPILER(CLANG) -#pragma clang diagnostic pop -#endif -} - -void PluginProcessProxy::setFullscreenWindowIsShowing(bool fullscreenWindowIsShowing) -{ - if (m_fullscreenWindowIsShowing == fullscreenWindowIsShowing) - return; - - m_fullscreenWindowIsShowing = fullscreenWindowIsShowing; - if (m_fullscreenWindowIsShowing) - enterFullscreen(); - else - exitFullscreen(); -} - -void PluginProcessProxy::enterFullscreen() -{ - // Get the current presentation options. - m_preFullscreenAppPresentationOptions = [NSApp presentationOptions]; - - // Figure out which presentation options to use. - unsigned presentationOptions = m_preFullscreenAppPresentationOptions & ~(NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar); - presentationOptions |= NSApplicationPresentationHideDock | NSApplicationPresentationHideMenuBar; - - [NSApp setPresentationOptions:presentationOptions]; - makePluginProcessTheFrontProcess(); -} - -void PluginProcessProxy::exitFullscreen() -{ - // If the plug-in host is the current application then we should bring ourselves to the front when it exits full-screen mode. - ProcessSerialNumber frontProcessSerialNumber; -#if COMPILER(CLANG) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif - GetFrontProcess(&frontProcessSerialNumber); -#if COMPILER(CLANG) -#pragma clang diagnostic pop -#endif - - // The UI process must be the front process in order to change the presentation mode. - makeUIProcessTheFrontProcess(); - [NSApp setPresentationOptions:m_preFullscreenAppPresentationOptions]; - - ProcessSerialNumber pluginProcessSerialNumber; - if (!getPluginProcessSerialNumber(pluginProcessSerialNumber)) - return; - - // If the plug-in process was not the front process, switch back to the previous front process. - // (Otherwise we'll keep the UI process as the front process). - Boolean isPluginProcessFrontProcess; -#if COMPILER(CLANG) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif - SameProcess(&frontProcessSerialNumber, &pluginProcessSerialNumber, &isPluginProcessFrontProcess); -#if COMPILER(CLANG) -#pragma clang diagnostic pop -#endif - if (!isPluginProcessFrontProcess) { -#if COMPILER(CLANG) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#endif - SetFrontProcess(&frontProcessSerialNumber); -#if COMPILER(CLANG) -#pragma clang diagnostic pop -#endif - } -} - -void PluginProcessProxy::setModalWindowIsShowing(bool modalWindowIsShowing) -{ - if (modalWindowIsShowing == m_modalWindowIsShowing) - return; - - m_modalWindowIsShowing = modalWindowIsShowing; - - if (m_modalWindowIsShowing) - beginModal(); - else - endModal(); -} - -void PluginProcessProxy::beginModal() -{ - ASSERT(!m_placeholderWindow); - ASSERT(!m_activationObserver); - - m_placeholderWindow = adoptNS([[WKPlaceholderModalWindow alloc] initWithContentRect:NSMakeRect(0, 0, 1, 1) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]); - [m_placeholderWindow.get() setReleasedWhenClosed:NO]; - - m_activationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationWillBecomeActiveNotification object:NSApp queue:nil - usingBlock:^(NSNotification *){ applicationDidBecomeActive(); }]; - - // The call to -[NSApp runModalForWindow:] below will run a nested run loop, and if the plug-in process - // crashes the PluginProcessProxy object can be destroyed. Protect against this here. - RefPtr<PluginProcessProxy> protect(this); - - [NSApp runModalForWindow:m_placeholderWindow.get()]; - - [m_placeholderWindow.get() orderOut:nil]; - m_placeholderWindow = nullptr; -} - -void PluginProcessProxy::endModal() -{ - ASSERT(m_placeholderWindow); - ASSERT(m_activationObserver); - - [[NSNotificationCenter defaultCenter] removeObserver:m_activationObserver.get()]; - m_activationObserver = nullptr; - - [NSApp stopModal]; - - makeUIProcessTheFrontProcess(); -} - -void PluginProcessProxy::applicationDidBecomeActive() -{ - makePluginProcessTheFrontProcess(); -} - -void PluginProcessProxy::setProcessSuppressionEnabled(bool processSuppressionEnabled) -{ - if (!isValid()) - return; - - m_connection->send(Messages::PluginProcess::SetProcessSuppressionEnabled(processSuppressionEnabled), 0); -} - -void PluginProcessProxy::openPluginPreferencePane() -{ - if (!m_pluginProcessAttributes.moduleInfo.preferencePanePath) - return; - - NSURL *preferenceURL = [NSURL fileURLWithPath:m_pluginProcessAttributes.moduleInfo.preferencePanePath]; - if (!preferenceURL) { - LOG_ERROR("Creating URL for preference pane path \"%@\" failed.", (NSString *)m_pluginProcessAttributes.moduleInfo.preferencePanePath); - return; - } - - NSArray *preferenceURLs = [NSArray arrayWithObject:preferenceURL]; - - LSLaunchURLSpec prefSpec; - prefSpec.appURL = 0; - prefSpec.itemURLs = reinterpret_cast<CFArrayRef>(preferenceURLs); - prefSpec.passThruParams = 0; - prefSpec.launchFlags = kLSLaunchAsync | kLSLaunchDontAddToRecents; - prefSpec.asyncRefCon = 0; - - OSStatus error = LSOpenFromURLSpec(&prefSpec, 0); - if (error != noErr) - LOG_ERROR("LSOpenFromURLSpec to open \"%@\" failed with error %d.", (NSString *)m_pluginProcessAttributes.moduleInfo.preferencePanePath, error); -} - -static bool isFlashUpdater(const String& launchPath, const Vector<String>& arguments) -{ - if (launchPath != "/Applications/Utilities/Adobe Flash Player Install Manager.app/Contents/MacOS/Adobe Flash Player Install Manager") - return false; - - if (arguments.size() != 1) - return false; - - if (arguments[0] != "-update") - return false; - - return true; -} - -static bool shouldLaunchProcess(const PluginProcessAttributes& pluginProcessAttributes, const String& launchPath, const Vector<String>& arguments) -{ - if (pluginProcessAttributes.moduleInfo.bundleIdentifier == "com.macromedia.Flash Player.plugin") - return isFlashUpdater(launchPath, arguments); - - return false; -} - -void PluginProcessProxy::launchProcess(const String& launchPath, const Vector<String>& arguments, bool& result) -{ - if (!shouldLaunchProcess(m_pluginProcessAttributes, launchPath, arguments)) { - result = false; - return; - } - - result = true; - - RetainPtr<NSMutableArray> argumentsArray = adoptNS([[NSMutableArray alloc] initWithCapacity:arguments.size()]); - for (size_t i = 0; i < arguments.size(); ++i) - [argumentsArray addObject:(NSString *)arguments[i]]; - - [NSTask launchedTaskWithLaunchPath:launchPath arguments:argumentsArray.get()]; -} - -static bool isJavaUpdaterURL(const PluginProcessAttributes& pluginProcessAttributes, const String& urlString) -{ - NSURL *url = [NSURL URLWithString:urlString]; - if (![url isFileURL]) - return false; - - NSString *javaUpdaterPath = [NSString pathWithComponents:[NSArray arrayWithObjects:(NSString *)pluginProcessAttributes.moduleInfo.path, @"Contents/Resources/Java Updater.app", nil]]; - return [url.path isEqualToString:javaUpdaterPath]; -} - -static bool shouldLaunchApplicationAtURL(const PluginProcessAttributes& pluginProcessAttributes, const String& urlString) -{ - if (pluginProcessAttributes.moduleInfo.bundleIdentifier == "com.oracle.java.JavaAppletPlugin") - return isJavaUpdaterURL(pluginProcessAttributes, urlString); - - return false; -} - -void PluginProcessProxy::launchApplicationAtURL(const String& urlString, const Vector<String>& arguments, bool& result) -{ - if (!shouldLaunchApplicationAtURL(m_pluginProcessAttributes, urlString)) { - result = false; - return; - } - - result = true; - - RetainPtr<NSMutableArray> argumentsArray = adoptNS([[NSMutableArray alloc] initWithCapacity:arguments.size()]); - for (size_t i = 0; i < arguments.size(); ++i) - [argumentsArray addObject:(NSString *)arguments[i]]; - - NSDictionary *configuration = [NSDictionary dictionaryWithObject:argumentsArray.get() forKey:NSWorkspaceLaunchConfigurationArguments]; - [[NSWorkspace sharedWorkspace] launchApplicationAtURL:[NSURL URLWithString:urlString] options:NSWorkspaceLaunchAsync configuration:configuration error:nullptr]; -} - -static bool isSilverlightPreferencesURL(const PluginProcessAttributes& pluginProcessAttributes, const String& urlString) -{ - NSURL *silverlightPreferencesURL = [NSURL fileURLWithPathComponents:[NSArray arrayWithObjects:(NSString *)pluginProcessAttributes.moduleInfo.path, @"Contents/Resources/Silverlight Preferences.app", nil]]; - - return [[NSURL URLWithString:urlString] isEqual:silverlightPreferencesURL]; -} - -static bool shouldOpenURL(const PluginProcessAttributes& pluginProcessAttributes, const String& urlString) -{ - if (pluginProcessAttributes.moduleInfo.bundleIdentifier == "com.microsoft.SilverlightPlugin") - return isSilverlightPreferencesURL(pluginProcessAttributes, urlString); - - return false; -} - -void PluginProcessProxy::openURL(const String& urlString, bool& result, int32_t& status, String& launchedURLString) -{ - if (!shouldOpenURL(m_pluginProcessAttributes, urlString)) { - result = false; - return; - } - - result = true; - CFURLRef launchedURL; - status = LSOpenCFURLRef(KURL(ParsedURLString, urlString).createCFURL().get(), &launchedURL); - - if (launchedURL) { - launchedURLString = KURL(launchedURL).string(); - CFRelease(launchedURL); - } - - result = false; -} - -} // namespace WebKit - -#endif // ENABLE(PLUGIN_PROCESS) diff --git a/Source/WebKit2/UIProcess/Plugins/qt/PluginProcessProxyQt.cpp b/Source/WebKit2/UIProcess/Plugins/qt/PluginProcessProxyQt.cpp index 47b118a4b..ff5ed76de 100644 --- a/Source/WebKit2/UIProcess/Plugins/qt/PluginProcessProxyQt.cpp +++ b/Source/WebKit2/UIProcess/Plugins/qt/PluginProcessProxyQt.cpp @@ -44,15 +44,14 @@ #include <QStringBuilder> #include <QVariant> #include <WebCore/FileSystem.h> -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> namespace WebKit { -class PluginProcessCreationParameters; +struct PluginProcessCreationParameters; void PluginProcessProxy::platformGetLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions, const PluginProcessAttributes& pluginProcessAttributes) { + launchOptions.processType = ProcessLauncher::ProcessType::Plugin64; launchOptions.extraInitializationData.add("plugin-path", pluginProcessAttributes.moduleInfo.path); } @@ -60,23 +59,25 @@ void PluginProcessProxy::platformInitializePluginProcess(PluginProcessCreationPa { } -static PassOwnPtr<QFile> cacheFile() +#if PLUGIN_ARCHITECTURE(X11) + +static std::unique_ptr<QFile> cacheFile() { QString cachePath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); if (cachePath.isEmpty()) - return PassOwnPtr<QFile>(); + return std::make_unique<QFile>(); // This should match the path set through WKContextSetDiskCacheDirectory. cachePath.append(QDir::separator()).append(QStringLiteral(".QtWebKit")).append(QDir::separator()); QString cacheFilePath = cachePath % QStringLiteral("plugin_meta_data.json"); QDir::root().mkpath(cachePath); - return adoptPtr(new QFile(cacheFilePath)); + return std::make_unique<QFile>(cacheFilePath); } static void removeCacheFile() { - if (OwnPtr<QFile> file = cacheFile()) + if (auto file = cacheFile()) file->remove(); } @@ -90,7 +91,7 @@ struct ReadResult { static ReadResult::Tag readMetaDataFromCacheFile(QJsonDocument& result) { - OwnPtr<QFile> file = cacheFile(); + auto file = cacheFile(); if (!file || !file->open(QFile::ReadOnly)) return ReadResult::Empty; QByteArray data = file->readAll(); @@ -110,7 +111,7 @@ static ReadResult::Tag readMetaDataFromCacheFile(QJsonDocument& result) static void writeToCacheFile(const QJsonArray& array) { - OwnPtr<QFile> file = cacheFile(); + auto file = cacheFile(); if (file && file->open(QFile::WriteOnly | QFile::Truncate)) // Don't care about write error here. We will detect it later. file->write(QJsonDocument(array).toJson()); @@ -168,7 +169,7 @@ static MetaDataResult::Tag tryReadPluginMetaDataFromCacheFile(const QString& can return MetaDataResult::NotAvailable; } - if (object.contains(QLatin1String("unloadable"))) + if (object.contains(QStringLiteral("unloadable"))) return MetaDataResult::Unloadable; // Match. @@ -213,11 +214,8 @@ bool PluginProcessProxy::scanPlugin(const String& pluginPath, RawPluginMetaData& && process.exitCode() == EXIT_SUCCESS; if (ranSuccessfully) { QByteArray outputBytes = process.readAll(); - ASSERT(!(outputBytes.size() % sizeof(UChar))); - - String output(reinterpret_cast<const UChar*>(outputBytes.constData()), outputBytes.size() / sizeof(UChar)); Vector<String> lines; - output.split(UChar('\n'), true, lines); + String::fromUTF8(outputBytes.data(), outputBytes.size()).split('\n', true, lines); ASSERT(lines.size() == 4 && lines.last().isEmpty()); result.name.swap(lines[0]); @@ -246,6 +244,8 @@ bool PluginProcessProxy::scanPlugin(const String& pluginPath, RawPluginMetaData& return true; } +#endif // PLUGIN_ARCHITECTURE(X11) + } // namespace WebKit #endif // ENABLE(PLUGIN_PROCESS) diff --git a/Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp b/Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp index 3726401f6..35afe9fab 100644 --- a/Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp +++ b/Source/WebKit2/UIProcess/Plugins/unix/PluginInfoStoreUnix.cpp @@ -32,50 +32,21 @@ #include "PluginInfoStore.h" #include "NetscapePluginModule.h" -#include "PluginDatabase.h" +#include "PluginSearchPath.h" +#include "ProcessExecutablePath.h" #include <WebCore/FileSystem.h> +#if PLATFORM(GTK) +#include "PluginInfoCache.h" +#endif + using namespace WebCore; namespace WebKit { Vector<String> PluginInfoStore::pluginsDirectories() { - Vector<String> result; - - result.append(homeDirectoryPath() + "/.mozilla/plugins"); - result.append(homeDirectoryPath() + "/.netscape/plugins"); - result.append("/usr/lib/browser/plugins"); - result.append("/usr/local/lib/mozilla/plugins"); - result.append("/usr/lib/firefox/plugins"); - result.append("/usr/lib64/browser-plugins"); - result.append("/usr/lib/browser-plugins"); - result.append("/usr/lib/mozilla/plugins"); - result.append("/usr/local/netscape/plugins"); - result.append("/opt/mozilla/plugins"); - result.append("/opt/mozilla/lib/plugins"); - result.append("/opt/netscape/plugins"); - result.append("/opt/netscape/communicator/plugins"); - result.append("/usr/lib/netscape/plugins"); - result.append("/usr/lib/netscape/plugins-libc5"); - result.append("/usr/lib/netscape/plugins-libc6"); - result.append("/usr/lib64/netscape/plugins"); - result.append("/usr/lib64/mozilla/plugins"); - result.append("/usr/lib/nsbrowser/plugins"); - result.append("/usr/lib64/nsbrowser/plugins"); - - String mozillaHome(getenv("MOZILLA_HOME")); - if (!mozillaHome.isEmpty()) - result.append(mozillaHome + "/plugins"); - - String mozillaPaths(getenv("MOZ_PLUGIN_PATH")); - if (!mozillaPaths.isEmpty()) { - Vector<String> paths; - mozillaPaths.split(UChar(':'), /* allowEmptyEntries */ false, paths); - result.appendVector(paths); - } - - return result; + return WebKit::pluginsDirectories(); } Vector<String> PluginInfoStore::pluginPathsInDirectory(const String& directory) @@ -98,7 +69,27 @@ Vector<String> PluginInfoStore::individualPluginPaths() bool PluginInfoStore::getPluginInfo(const String& pluginPath, PluginModuleInfo& plugin) { +#if PLATFORM(GTK) + if (PluginInfoCache::singleton().getPluginInfo(pluginPath, plugin)) { +#if ENABLE(PLUGIN_PROCESS_GTK2) + if (plugin.requiresGtk2) { + String pluginProcessPath = executablePathOfPluginProcess(); + pluginProcessPath.append('2'); + if (!fileExists(pluginProcessPath)) + return false; + } +#endif + return true; + } + + if (NetscapePluginModule::getPluginInfo(pluginPath, plugin)) { + PluginInfoCache::singleton().updatePluginInfo(pluginPath, plugin); + return true; + } + return false; +#else return NetscapePluginModule::getPluginInfo(pluginPath, plugin); +#endif } bool PluginInfoStore::shouldUsePlugin(Vector<PluginModuleInfo>& /*alreadyLoadedPlugins*/, const PluginModuleInfo& /*plugin*/) diff --git a/Source/WebKit2/UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp b/Source/WebKit2/UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp index d52cae647..a6c52f8b4 100644 --- a/Source/WebKit2/UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp +++ b/Source/WebKit2/UIProcess/Plugins/unix/PluginProcessProxyUnix.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Igalia S.L. + * Copyright (C) 2011, 2014 Igalia S.L. * Copyright (C) 2011 Apple Inc. * Copyright (C) 2012 Samsung Electronics * @@ -33,11 +33,17 @@ #include "PluginProcessCreationParameters.h" #include "ProcessExecutablePath.h" #include <WebCore/FileSystem.h> +#include <sys/wait.h> #include <wtf/text/CString.h> #include <wtf/text/WTFString.h> + #if PLATFORM(GTK) || PLATFORM(EFL) #include <glib.h> -#include <wtf/gobject/GOwnPtr.h> +#include <wtf/glib/GUniquePtr.h> +#endif + +#if PLATFORM(GTK) +#include "Module.h" #endif using namespace WebCore; @@ -46,67 +52,108 @@ namespace WebKit { void PluginProcessProxy::platformGetLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions, const PluginProcessAttributes& pluginProcessAttributes) { -#if PLATFORM(EFL) && !defined(NDEBUG) - const char* commandPrefix = getenv("PLUGIN_PROCESS_COMMAND_PREFIX"); - if (commandPrefix && *commandPrefix) - launchOptions.processCmdPrefix = String::fromUTF8(commandPrefix); -#endif + launchOptions.processType = ProcessLauncher::ProcessType::Plugin64; launchOptions.extraInitializationData.add("plugin-path", pluginProcessAttributes.moduleInfo.path); +#if PLATFORM(GTK) + if (pluginProcessAttributes.moduleInfo.requiresGtk2) + launchOptions.extraInitializationData.add("requires-gtk2", emptyString()); +#endif } void PluginProcessProxy::platformInitializePluginProcess(PluginProcessCreationParameters&) { } +#if PLATFORM(GTK) +static bool pluginRequiresGtk2(const String& pluginPath) +{ + std::unique_ptr<Module> module = std::make_unique<Module>(pluginPath); + if (!module->load()) + return false; + return module->functionPointer<gpointer>("gtk_object_get_type"); +} +#endif + +#if PLUGIN_ARCHITECTURE(X11) bool PluginProcessProxy::scanPlugin(const String& pluginPath, RawPluginMetaData& result) { #if PLATFORM(GTK) || PLATFORM(EFL) - CString binaryPath = fileSystemRepresentation(executablePathOfPluginProcess()); + String pluginProcessPath = executablePathOfPluginProcess(); + +#if PLATFORM(GTK) + bool requiresGtk2 = pluginRequiresGtk2(pluginPath); + if (requiresGtk2) { +#if ENABLE(PLUGIN_PROCESS_GTK2) + pluginProcessPath.append('2'); + if (!fileExists(pluginProcessPath)) + return false; +#else + return false; +#endif + } +#endif + + CString binaryPath = fileSystemRepresentation(pluginProcessPath); CString pluginPathCString = fileSystemRepresentation(pluginPath); char* argv[4]; argv[0] = const_cast<char*>(binaryPath.data()); argv[1] = const_cast<char*>("-scanPlugin"); argv[2] = const_cast<char*>(pluginPathCString.data()); - argv[3] = 0; - - int status; - GOwnPtr<char> stdOut; + argv[3] = nullptr; // If the disposition of SIGCLD signal is set to SIG_IGN (default) // then the signal will be ignored and g_spawn_sync() will not be // able to return the status. // As a consequence, we make sure that the disposition is set to // SIG_DFL before calling g_spawn_sync(). +#if defined(SIGCLD) struct sigaction action; sigaction(SIGCLD, 0, &action); if (action.sa_handler == SIG_IGN) { action.sa_handler = SIG_DFL; sigaction(SIGCLD, &action, 0); } +#endif - if (!g_spawn_sync(0, argv, 0, G_SPAWN_STDERR_TO_DEV_NULL, 0, 0, &stdOut.outPtr(), 0, &status, 0)) + int status; + GUniqueOutPtr<char> stdOut; + GUniqueOutPtr<GError> error; + if (!g_spawn_sync(nullptr, argv, nullptr, G_SPAWN_STDERR_TO_DEV_NULL, nullptr, nullptr, &stdOut.outPtr(), nullptr, &status, &error.outPtr())) { + WTFLogAlways("Failed to launch %s: %s", argv[0], error->message); return false; + } - if (!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS || !stdOut) + if (!WIFEXITED(status) || WEXITSTATUS(status) != EXIT_SUCCESS) { + WTFLogAlways("Error scanning plugin %s, %s returned %d exit status", argv[2], argv[0], status); return false; + } - String stdOutString(reinterpret_cast<const UChar*>(stdOut.get())); + if (!stdOut) { + WTFLogAlways("Error scanning plugin %s, %s didn't write any output to stdout", argv[2], argv[0]); + return false; + } Vector<String> lines; - stdOutString.split(UChar('\n'), true, lines); + String::fromUTF8(stdOut.get()).split(UChar('\n'), true, lines); - if (lines.size() < 3) + if (lines.size() < 3) { + WTFLogAlways("Error scanning plugin %s, too few lines of output provided", argv[2]); return false; + } result.name.swap(lines[0]); result.description.swap(lines[1]); result.mimeDescription.swap(lines[2]); +#if PLATFORM(GTK) + result.requiresGtk2 = requiresGtk2; +#endif return !result.mimeDescription.isEmpty(); #else // PLATFORM(GTK) || PLATFORM(EFL) return false; #endif // PLATFORM(GTK) || PLATFORM(EFL) } +#endif // PLUGIN_ARCHITECTURE(X11) } // namespace WebKit |
