Changeset 218419 in webkit


Ignore:
Timestamp:
Jun 16, 2017 3:32:34 PM (7 years ago)
Author:
Chris Dumez
Message:

[WK2] Add WKProcessPool SPI to efficiently reset all plugin load client policies
https://bugs.webkit.org/show_bug.cgi?id=173472
<rdar://problem/28858817>

Reviewed by Brady Eidson.

Source/WebCore:

Add PluginLoadClientPolicyMaximum value to PluginLoadClientPolicy enumeration
to facilitate input value validation on API side.

  • plugins/PluginData.h:

Source/WebKit2:

Add WKProcessPool SPI to efficiently reset all plugin load client policies:
[WKProcessPool _resetPluginLoadClientPolicies]. This new SPI clears all
existing policies and then sets all of them with new values, with a
minimal amount of IPC.

To achieve this, clients would previously have to call

  1. WKContextClearPluginClientPolicies() which would cause a broadcast IPC to every WebContent process.
  2. WKContextSetPluginLoadClientPolicy() repeatedly to add each policy one by one. Each call to WKContextSetPluginLoadClientPolicy() would cause a broadcast IPC to every WebContent process.

The new SPI does the same job with a single broadcast IPC to every WebContent
process.

  • UIProcess/API/Cocoa/WKProcessPool.mm:

(isPluginLoadClientPolicyAcceptable):
(toPluginLoadClientPoliciesHashMap):
(policiesHashMapToDictionary):
(-[WKProcessPool _resetPluginLoadClientPolicies:]):
(-[WKProcessPool _pluginLoadClientPolicies]):

  • UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
  • UIProcess/WebProcessPool.cpp:

(WebKit::WebProcessPool::setPluginLoadClientPolicy):
(WebKit::WebProcessPool::resetPluginLoadClientPolicies):

  • UIProcess/WebProcessPool.h:
  • WebProcess/WebProcess.cpp:

(WebKit::WebProcess::initializeWebProcess):
(WebKit::WebProcess::resetPluginLoadClientPolicies):

  • WebProcess/WebProcess.h:
  • WebProcess/WebProcess.messages.in:

Tools:

Add API test coverage.

  • TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
  • TestWebKitAPI/Tests/WebKit2Cocoa/PluginLoadClientPolicies.mm: Added.

(TEST):

Location:
trunk
Files:
1 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r218417 r218419  
     12017-06-16  Chris Dumez  <cdumez@apple.com>
     2
     3        [WK2] Add WKProcessPool SPI to efficiently reset all plugin load client policies
     4        https://bugs.webkit.org/show_bug.cgi?id=173472
     5        <rdar://problem/28858817>
     6
     7        Reviewed by Brady Eidson.
     8
     9        Add PluginLoadClientPolicyMaximum value to PluginLoadClientPolicy enumeration
     10        to facilitate input value validation on API side.
     11
     12        * plugins/PluginData.h:
     13
    1142017-06-16  Jer Noble  <jer.noble@apple.com>
    215
  • trunk/Source/WebCore/plugins/PluginData.h

    r211877 r218419  
    4646    // The plug-in module should be loaded irrespective of whether WebKit has asked it to be blocked.
    4747    PluginLoadClientPolicyAllowAlways,
     48
     49    PluginLoadClientPolicyMaximum = PluginLoadClientPolicyAllowAlways
    4850};
    4951
  • trunk/Source/WebKit2/ChangeLog

    r218418 r218419  
     12017-06-16  Chris Dumez  <cdumez@apple.com>
     2
     3        [WK2] Add WKProcessPool SPI to efficiently reset all plugin load client policies
     4        https://bugs.webkit.org/show_bug.cgi?id=173472
     5        <rdar://problem/28858817>
     6
     7        Reviewed by Brady Eidson.
     8
     9        Add WKProcessPool SPI to efficiently reset all plugin load client policies:
     10        [WKProcessPool _resetPluginLoadClientPolicies]. This new SPI clears all
     11        existing policies and then sets all of them with new values, with a
     12        minimal amount of IPC.
     13
     14        To achieve this, clients would previously have to call
     15        1. WKContextClearPluginClientPolicies() which would cause a broadcast IPC to
     16           every WebContent process.
     17        2. WKContextSetPluginLoadClientPolicy() repeatedly to add each policy one by
     18           one. Each call to WKContextSetPluginLoadClientPolicy() would cause a broadcast
     19           IPC to every WebContent process.
     20
     21        The new SPI does the same job with a single broadcast IPC to every WebContent
     22        process.
     23
     24        * UIProcess/API/Cocoa/WKProcessPool.mm:
     25        (isPluginLoadClientPolicyAcceptable):
     26        (toPluginLoadClientPoliciesHashMap):
     27        (policiesHashMapToDictionary):
     28        (-[WKProcessPool _resetPluginLoadClientPolicies:]):
     29        (-[WKProcessPool _pluginLoadClientPolicies]):
     30        * UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
     31        * UIProcess/WebProcessPool.cpp:
     32        (WebKit::WebProcessPool::setPluginLoadClientPolicy):
     33        (WebKit::WebProcessPool::resetPluginLoadClientPolicies):
     34        * UIProcess/WebProcessPool.h:
     35        * WebProcess/WebProcess.cpp:
     36        (WebKit::WebProcess::initializeWebProcess):
     37        (WebKit::WebProcess::resetPluginLoadClientPolicies):
     38        * WebProcess/WebProcess.h:
     39        * WebProcess/WebProcess.messages.in:
     40
    1412017-06-16  Brent Fulgham  <bfulgham@apple.com>
    242
  • trunk/Source/WebKit2/UIProcess/API/Cocoa/WKProcessPool.mm

    r215991 r218419  
    3232#import "CacheModel.h"
    3333#import "DownloadClient.h"
     34#import "Logging.h"
    3435#import "SandboxUtilities.h"
    3536#import "UIGamepadProvider.h"
     
    4647#import <WebCore/CFNetworkSPI.h>
    4748#import <WebCore/CertificateInfo.h>
     49#import <WebCore/PluginData.h>
    4850#import <wtf/RetainPtr.h>
    4951
     
    249251}
    250252
     253#if !TARGET_OS_IPHONE
     254
     255#if ENABLE(NETSCAPE_PLUGIN_API)
     256
     257static bool isPluginLoadClientPolicyAcceptable(unsigned policy)
     258{
     259    return policy <= WebCore::PluginLoadClientPolicyMaximum;
     260}
     261static HashMap<String, HashMap<String, HashMap<String, uint8_t>>> toPluginLoadClientPoliciesHashMap(NSDictionary* dictionary)
     262{
     263    __block HashMap<String, HashMap<String, HashMap<String, uint8_t>>> pluginLoadClientPolicies;
     264    [dictionary enumerateKeysAndObjectsUsingBlock:^(id nsHost, id nsPoliciesForHost, BOOL *stop) {
     265        if (![nsHost isKindOfClass:[NSString class]]) {
     266            RELEASE_LOG_ERROR(Plugins, "_resetPluginLoadClientPolicies was called with dictionary in wrong format");
     267            return;
     268        }
     269        if (![nsPoliciesForHost isKindOfClass:[NSDictionary class]]) {
     270            RELEASE_LOG_ERROR(Plugins, "_resetPluginLoadClientPolicies was called with dictionary in wrong format");
     271            return;
     272        }
     273
     274        String host = (NSString *)nsHost;
     275        __block HashMap<String, HashMap<String, uint8_t>> policiesForHost;
     276        [nsPoliciesForHost enumerateKeysAndObjectsUsingBlock:^(id nsIdentifier, id nsVersionsToPolicies, BOOL *stop) {
     277            if (![nsIdentifier isKindOfClass:[NSString class]]) {
     278                RELEASE_LOG_ERROR(Plugins, "_resetPluginLoadClientPolicies was called with dictionary in wrong format");
     279                return;
     280            }
     281            if (![nsVersionsToPolicies isKindOfClass:[NSDictionary class]]) {
     282                RELEASE_LOG_ERROR(Plugins, "_resetPluginLoadClientPolicies was called with dictionary in wrong format");
     283                return;
     284            }
     285
     286            String bundleIdentifier = (NSString *)nsIdentifier;
     287            __block HashMap<String, uint8_t> versionsToPolicies;
     288            [nsVersionsToPolicies enumerateKeysAndObjectsUsingBlock:^(id nsVersion, id nsPolicy, BOOL *stop) {
     289                if (![nsVersion isKindOfClass:[NSString class]]) {
     290                    RELEASE_LOG_ERROR(Plugins, "_resetPluginLoadClientPolicies was called with dictionary in wrong format");
     291                    return;
     292                }
     293                if (![nsPolicy isKindOfClass:[NSNumber class]]) {
     294                    RELEASE_LOG_ERROR(Plugins, "_resetPluginLoadClientPolicies was called with dictionary in wrong format");
     295                    return;
     296                }
     297                unsigned policy = ((NSNumber *)nsPolicy).unsignedIntValue;
     298                if (!isPluginLoadClientPolicyAcceptable(policy)) {
     299                    RELEASE_LOG_ERROR(Plugins, "_resetPluginLoadClientPolicies was called with dictionary in wrong format");
     300                    return;
     301                }
     302                String version = (NSString *)nsVersion;
     303                versionsToPolicies.add(version, static_cast<uint8_t>(policy));
     304            }];
     305            if (!versionsToPolicies.isEmpty())
     306                policiesForHost.add(bundleIdentifier, WTFMove(versionsToPolicies));
     307        }];
     308        if (!policiesForHost.isEmpty())
     309            pluginLoadClientPolicies.add(host, WTFMove(policiesForHost));
     310    }];
     311    return pluginLoadClientPolicies;
     312}
     313
     314static NSDictionary *policiesHashMapToDictionary(const HashMap<String, HashMap<String, HashMap<String, uint8_t>>>& map)
     315{
     316    NSMutableDictionary *policies = [[NSMutableDictionary alloc] init];
     317    for (auto& hostPair : map) {
     318        NSString *host = hostPair.key;
     319        policies[host] = [[NSMutableDictionary alloc] init];
     320        for (auto& bundleIdentifierPair : hostPair.value) {
     321            NSString *bundlerIdentifier = bundleIdentifierPair.key;
     322            policies[host][bundlerIdentifier] = [[NSMutableDictionary alloc] init];
     323            for (auto& versionPair : bundleIdentifierPair.value) {
     324                NSString *version = versionPair.key;
     325                policies[host][bundlerIdentifier][version] = [NSNumber numberWithUnsignedInt:versionPair.value];
     326            }
     327        }
     328    }
     329    return policies;
     330}
     331
     332#endif
     333
     334- (void)_resetPluginLoadClientPolicies:(NSDictionary *)policies
     335{
     336#if ENABLE(NETSCAPE_PLUGIN_API)
     337    _processPool->resetPluginLoadClientPolicies(toPluginLoadClientPoliciesHashMap(policies));
     338#endif
     339}
     340
     341-(NSDictionary *)_pluginLoadClientPolicies
     342{
     343    auto& map = _processPool->pluginLoadClientPolicies();
     344    return policiesHashMapToDictionary(map);
     345}
     346#endif
     347
    251348
    252349- (id <_WKDownloadDelegate>)_downloadDelegate
  • trunk/Source/WebKit2/UIProcess/API/Cocoa/WKProcessPoolPrivate.h

    r215991 r218419  
    5353- (void)_setObjectsForBundleParametersWithDictionary:(NSDictionary *)dictionary WK_API_AVAILABLE(macosx(10.12), ios(10.0));
    5454
     55#if !TARGET_OS_IPHONE
     56- (void)_resetPluginLoadClientPolicies:(NSDictionary *)policies WK_API_AVAILABLE(macosx(WK_MAC_TBA));
     57@property (nonatomic, readonly, copy) NSDictionary *_pluginLoadClientPolicies WK_API_AVAILABLE(macosx(WK_MAC_TBA));
     58#endif
     59
    5560@property (nonatomic, weak, setter=_setDownloadDelegate:) id <_WKDownloadDelegate> _downloadDelegate;
    5661@property (nonatomic, weak, setter=_setAutomationDelegate:) id <_WKAutomationDelegate> _automationDelegate WK_API_AVAILABLE(macosx(10.12), ios(10.0));
  • trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp

    r218261 r218419  
    15891589void WebProcessPool::setPluginLoadClientPolicy(WebCore::PluginLoadClientPolicy policy, const String& host, const String& bundleIdentifier, const String& versionString)
    15901590{
    1591     HashMap<String, HashMap<String, uint8_t>> policiesByIdentifier;
    1592     if (m_pluginLoadClientPolicies.contains(host))
    1593         policiesByIdentifier = m_pluginLoadClientPolicies.get(host);
    1594 
    1595     HashMap<String, uint8_t> versionsToPolicies;
    1596     if (policiesByIdentifier.contains(bundleIdentifier))
    1597         versionsToPolicies = policiesByIdentifier.get(bundleIdentifier);
    1598 
     1591    auto& policiesForHost = m_pluginLoadClientPolicies.ensure(host, [] { return HashMap<String, HashMap<String, uint8_t>>(); }).iterator->value;
     1592    auto& versionsToPolicies = policiesForHost.ensure(bundleIdentifier, [] { return HashMap<String, uint8_t>(); }).iterator->value;
    15991593    versionsToPolicies.set(versionString, policy);
    1600     policiesByIdentifier.set(bundleIdentifier, versionsToPolicies);
    1601     m_pluginLoadClientPolicies.set(host, policiesByIdentifier);
    16021594
    16031595    sendToAllProcesses(Messages::WebProcess::SetPluginLoadClientPolicy(policy, host, bundleIdentifier, versionString));
     1596}
     1597
     1598void WebProcessPool::resetPluginLoadClientPolicies(const HashMap<String, HashMap<String, HashMap<String, uint8_t>>>& pluginLoadClientPolicies)
     1599{
     1600    m_pluginLoadClientPolicies.clear();
     1601
     1602    for (auto& hostPair : pluginLoadClientPolicies) {
     1603        auto& policiesForHost = m_pluginLoadClientPolicies.ensure(hostPair.key, [] { return HashMap<String, HashMap<String, uint8_t>>(); }).iterator->value;
     1604        for (auto& bundleIdentifierPair : hostPair.value) {
     1605            auto& versionsToPolicies = policiesForHost.ensure(bundleIdentifierPair.key, [] { return HashMap<String, uint8_t>(); }).iterator->value;
     1606            for (auto& versionPair : bundleIdentifierPair.value)
     1607                versionsToPolicies.set(versionPair.key, versionPair.value);
     1608        }
     1609    }
     1610    sendToAllProcesses(Messages::WebProcess::ResetPluginLoadClientPolicies(m_pluginLoadClientPolicies));
    16041611}
    16051612
  • trunk/Source/WebKit2/UIProcess/WebProcessPool.h

    r218261 r218419  
    198198
    199199    void setPluginLoadClientPolicy(WebCore::PluginLoadClientPolicy, const String& host, const String& bundleIdentifier, const String& versionString);
     200    void resetPluginLoadClientPolicies(const HashMap<String, HashMap<String, HashMap<String, uint8_t>>>&);
    200201    void clearPluginClientPolicies();
     202    const HashMap<String, HashMap<String, HashMap<String, uint8_t>>>& pluginLoadClientPolicies() const { return m_pluginLoadClientPolicies; }
    201203#endif
    202204
  • trunk/Source/WebKit2/WebProcess/WebProcess.cpp

    r217908 r218419  
    401401
    402402#if ENABLE(NETSCAPE_PLUGIN_API) && PLATFORM(MAC)
    403     for (auto hostIter = parameters.pluginLoadClientPolicies.begin(); hostIter != parameters.pluginLoadClientPolicies.end(); ++hostIter) {
    404         for (auto bundleIdentifierIter = hostIter->value.begin(); bundleIdentifierIter != hostIter->value.end(); ++bundleIdentifierIter) {
    405             for (auto versionIter = bundleIdentifierIter->value.begin(); versionIter != bundleIdentifierIter->value.end(); ++versionIter)
    406                 WebPluginInfoProvider::singleton().setPluginLoadClientPolicy(static_cast<PluginLoadClientPolicy>(versionIter->value), hostIter->key, bundleIdentifierIter->key, versionIter->key);
    407         }
    408     }
     403    resetPluginLoadClientPolicies(parameters.pluginLoadClientPolicies);
    409404#endif
    410405
     
    924919#if ENABLE(NETSCAPE_PLUGIN_API) && PLATFORM(MAC)
    925920    WebPluginInfoProvider::singleton().setPluginLoadClientPolicy(static_cast<PluginLoadClientPolicy>(policy), host, bundleIdentifier, versionString);
     921#endif
     922}
     923
     924void WebProcess::resetPluginLoadClientPolicies(const HashMap<WTF::String, HashMap<WTF::String, HashMap<WTF::String, uint8_t>>>& pluginLoadClientPolicies)
     925{
     926#if ENABLE(NETSCAPE_PLUGIN_API) && PLATFORM(MAC)
     927    clearPluginClientPolicies();
     928
     929    for (auto& hostPair : pluginLoadClientPolicies) {
     930        for (auto& bundleIdentifierPair : hostPair.value) {
     931            for (auto& versionPair : bundleIdentifierPair.value)
     932                WebPluginInfoProvider::singleton().setPluginLoadClientPolicy(static_cast<PluginLoadClientPolicy>(versionPair.value), hostPair.key, bundleIdentifierPair.key, versionPair.key);
     933        }
     934    }
    926935#endif
    927936}
  • trunk/Source/WebKit2/WebProcess/WebProcess.h

    r217515 r218419  
    133133    void plugInDidReceiveUserInteraction(const String& pageOrigin, const String& pluginOrigin, const String& mimeType, WebCore::SessionID);
    134134    void setPluginLoadClientPolicy(uint8_t policy, const String& host, const String& bundleIdentifier, const String& versionString);
     135    void resetPluginLoadClientPolicies(const HashMap<String, HashMap<String, HashMap<String, uint8_t>>>&);
    135136    void clearPluginClientPolicies();
    136137    void refreshPlugins();
  • trunk/Source/WebKit2/WebProcess/WebProcess.messages.in

    r215941 r218419  
    5656    ResetPlugInAutoStartOriginHashes(HashMap<WebCore::SessionID, HashMap<uint32_t,double>> hashes)
    5757    SetPluginLoadClientPolicy(uint8_t policy, String host, String bundleIdentifier, String versionString)
     58    ResetPluginLoadClientPolicies(HashMap<String, HashMap<String, HashMap<String, uint8_t>>> pluginLoadClientPolicies)
    5859    ClearPluginClientPolicies()
    5960    RefreshPlugins()
  • trunk/Tools/ChangeLog

    r218409 r218419  
     12017-06-16  Chris Dumez  <cdumez@apple.com>
     2
     3        [WK2] Add WKProcessPool SPI to efficiently reset all plugin load client policies
     4        https://bugs.webkit.org/show_bug.cgi?id=173472
     5        <rdar://problem/28858817>
     6
     7        Reviewed by Brady Eidson.
     8
     9        Add API test coverage.
     10
     11        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
     12        * TestWebKitAPI/Tests/WebKit2Cocoa/PluginLoadClientPolicies.mm: Added.
     13        (TEST):
     14
    1152017-06-16  Brady Eidson  <beidson@apple.com>
    216
  • trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj

    r218399 r218419  
    485485                837A35F11D9A1E7D00663C57 /* DownloadRequestBlobURL.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 837A35F01D9A1E6400663C57 /* DownloadRequestBlobURL.html */; };
    486486                83B6DE6F1EE75221001E792F /* RestoreSessionState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83B6DE6E1EE7520F001E792F /* RestoreSessionState.cpp */; };
     487                83BAEE8D1EF4625500DDE894 /* PluginLoadClientPolicies.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83BAEE8C1EF4625500DDE894 /* PluginLoadClientPolicies.mm */; };
    487488                83DE134D1EF1C50800C1B355 /* ResponsivenessTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83DE134C1EF1C4FE00C1B355 /* ResponsivenessTimer.cpp */; };
    488489                8E4A85371E1D1AB200F53B0F /* GridPosition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8E4A85361E1D1AA100F53B0F /* GridPosition.cpp */; };
     
    12981299                83B6DE6E1EE7520F001E792F /* RestoreSessionState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RestoreSessionState.cpp; sourceTree = "<group>"; };
    12991300                83B88A331C80056D00BB2418 /* HTMLParserIdioms.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HTMLParserIdioms.cpp; sourceTree = "<group>"; };
     1301                83BAEE8C1EF4625500DDE894 /* PluginLoadClientPolicies.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PluginLoadClientPolicies.mm; sourceTree = "<group>"; };
    13001302                83DE134C1EF1C4FE00C1B355 /* ResponsivenessTimer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResponsivenessTimer.cpp; sourceTree = "<group>"; };
    13011303                86BD19971A2DB05B006DCF0A /* RefCounter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RefCounter.cpp; sourceTree = "<group>"; };
     
    17941796                                CEA6CF2219CCF5BD0064F5A7 /* OpenAndCloseWindow.mm */,
    17951797                                CEBCA12E1E3A660100C73293 /* OverrideContentSecurityPolicy.mm */,
     1798                                83BAEE8C1EF4625500DDE894 /* PluginLoadClientPolicies.mm */,
    17961799                                C95501BE19AD2FAF0049BE3E /* Preferences.mm */,
    17971800                                7C1AF7931E8DCBAB002645B9 /* PrepareForMoveToWindow.mm */,
     
    31083111                                515BE1711D428E4B00DD7C68 /* StoreBlobThenDelete.mm in Sources */,
    31093112                                7CCE7ED01A411A7E00447C4C /* StringByEvaluatingJavaScriptFromString.mm in Sources */,
     3113                                83BAEE8D1EF4625500DDE894 /* PluginLoadClientPolicies.mm in Sources */,
    31103114                                7CCE7ED11A411A7E00447C4C /* StringTruncator.mm in Sources */,
    31113115                                ECA680CE1E68CC0900731D20 /* StringUtilities.mm in Sources */,
Note: See TracChangeset for help on using the changeset viewer.