Changeset 258949 in webkit


Ignore:
Timestamp:
Mar 24, 2020 3:41:13 PM (4 years ago)
Author:
pvollan@apple.com
Message:

[Cocoa] Fix launch time regression with CF prefs direct mode enabled
https://bugs.webkit.org/show_bug.cgi?id=209244
Source/WebKit:

<rdar://problem/60542149>

Reviewed by Darin Adler.

When CF prefs direct mode was enabled in https://trac.webkit.org/changeset/258064/webkit, it introduced
a significant launch time regression. This patch addresses this regression. The number of observed domains
is reduced and domain observation is initiated later when Safari is first activated. Swizzling code is
removed, since that has a performance cost in the Objective-C runtime. Normal priority instead of
QOS_CLASS_BACKGROUND is used in the thread which starts the observing, since using a background priority
class can lead to priority inversion. Finally, a dictionary comparison is removed when a notification
about a preference change is received, since this check is redundant and doubles the cost of this method.

  • UIProcess/Cocoa/PreferenceObserver.mm:

(-[WKPreferenceObserver init]):

  • UIProcess/Cocoa/WebProcessPoolCocoa.mm:

(WebKit::WebProcessPool::platformInitialize):
(WebKit::WebProcessPool::registerNotificationObservers):
(WebKit::WebProcessPool::unregisterNotificationObservers):

  • UIProcess/WebProcessPool.h:

Source/WTF:

Reviewed by Darin Adler.

Re-enable CF prefs direct mode.

  • wtf/PlatformEnable.h:
  • wtf/PlatformEnableCocoa.h:

Tools:

Reviewed by Darin Adler.

  • TestWebKitAPI/Tests/WebKit/PreferenceChanges.mm:

(TEST):
(sharedInstanceMethodOverride):

Location:
trunk
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r258915 r258949  
     12020-03-24  Per Arne Vollan  <pvollan@apple.com>
     2
     3        [Cocoa] Fix launch time regression with CF prefs direct mode enabled
     4        https://bugs.webkit.org/show_bug.cgi?id=209244
     5
     6        Reviewed by Darin Adler.
     7
     8        Re-enable CF prefs direct mode.
     9
     10        * wtf/PlatformEnable.h:
     11        * wtf/PlatformEnableCocoa.h:
     12
    1132020-03-24  Per Arne Vollan  <pvollan@apple.com>
    214
  • trunk/Source/WTF/wtf/PlatformEnable.h

    r258557 r258949  
    554554#endif
    555555
     556#if !defined(ENABLE_CFPREFS_DIRECT_MODE)
     557#define ENABLE_CFPREFS_DIRECT_MODE 0
     558#endif
    556559
    557560
     
    871874#error "ENABLE(WEBGL2) requires ENABLE(WEBGL)"
    872875#endif
    873 
    874 #define ENABLE_CFPREFS_DIRECT_MODE 0
  • trunk/Source/WTF/wtf/PlatformEnableCocoa.h

    r258772 r258949  
    281281#define ENABLE_TAKE_UNBOUNDED_NETWORKING_ASSERTION 1
    282282#endif
     283
     284#if !defined(ENABLE_CFPREFS_DIRECT_MODE)
     285#define ENABLE_CFPREFS_DIRECT_MODE 1
     286#endif
  • trunk/Source/WebKit/ChangeLog

    r258945 r258949  
     12020-03-24  Per Arne Vollan  <pvollan@apple.com>
     2
     3        [Cocoa] Fix launch time regression with CF prefs direct mode enabled
     4        https://bugs.webkit.org/show_bug.cgi?id=209244
     5        <rdar://problem/60542149>
     6
     7        Reviewed by Darin Adler.
     8
     9        When CF prefs direct mode was enabled in https://trac.webkit.org/changeset/258064/webkit, it introduced
     10        a significant launch time regression. This patch addresses this regression. The number of observed domains
     11        is reduced and domain observation is initiated later when Safari is first activated. Swizzling code is
     12        removed, since that has a performance cost in the Objective-C runtime. Normal priority instead of
     13        QOS_CLASS_BACKGROUND is used in the thread which starts the observing, since using a background priority
     14        class can lead to priority inversion. Finally, a dictionary comparison is removed when a notification
     15        about a preference change is received, since this check is redundant and doubles the cost of this method.
     16
     17        * UIProcess/Cocoa/PreferenceObserver.mm:
     18        (-[WKPreferenceObserver init]):
     19        * UIProcess/Cocoa/WebProcessPoolCocoa.mm:
     20        (WebKit::WebProcessPool::platformInitialize):
     21        (WebKit::WebProcessPool::registerNotificationObservers):
     22        (WebKit::WebProcessPool::unregisterNotificationObservers):
     23        * UIProcess/WebProcessPool.h:
     24
    1252020-03-24  Daniel Bates  <dabates@apple.com>
    226
  • trunk/Source/WebKit/Resources/SandboxProfiles/ios/com.apple.WebKit.WebContent.sb

    r258915 r258949  
    535535    (global-name "com.apple.logd")
    536536    (global-name "com.apple.logd.events")
    537     (global-name "com.apple.cfprefsd.daemon")
    538537)
    539538
  • trunk/Source/WebKit/UIProcess/Cocoa/PreferenceObserver.h

    r258119 r258949  
    4747}
    4848+ (id)sharedInstance;
    49 + (void)swizzleRegisterDefaults;
    5049- (void)preferenceDidChange:(NSString *)domain key:(NSString *)key encodedValue:(NSString *)encodedValue;
    5150@end
  • trunk/Source/WebKit/UIProcess/Cocoa/PreferenceObserver.mm

    r258557 r258949  
    2929#import "WebProcessPool.h"
    3030
    31 #import <wtf/ObjCRuntimeExtras.h>
    32 
    33 static IMP registerDefaultsOriginal = nil;
    34 static bool registeringDefaults = false;
    35 
    36 static void registerDefaultsOverride(id self, SEL selector, NSDictionary<NSString *, id> *dictionary)
    37 {
    38     registeringDefaults = true;
    39     if (registerDefaultsOriginal)
    40         wtfCallIMP<void>(registerDefaultsOriginal, self, selector, dictionary);
    41     registeringDefaults = false;
    42 }
    43 
    4431@implementation WKUserDefaults
    4532
    4633- (void)_notifyObserversOfChangeFromValuesForKeys:(NSDictionary<NSString *, id> *)oldValues toValuesForKeys:(NSDictionary<NSString *, id> *)newValues
    4734{
    48     if (registeringDefaults)
    49         return;
    50 
    5135    [super _notifyObserversOfChangeFromValuesForKeys:oldValues toValuesForKeys:newValues];
    52 
    53     if ([oldValues isEqualToDictionary:newValues])
    54         return;
    5536
    5637    for (NSString *key in oldValues) {
     
    10283}
    10384
    104 + (void)swizzleRegisterDefaults
    105 {
    106     static std::once_flag onceFlag;
    107     std::call_once(onceFlag, [] {
    108         Method registerDefaultsMethod = class_getInstanceMethod(objc_getClass("NSUserDefaults"), @selector(registerDefaults:));
    109         registerDefaultsOriginal = method_setImplementation(registerDefaultsMethod, (IMP)registerDefaultsOverride);
    110     });
    111 }
    112 
    11385- (instancetype)init
    11486{
    11587    std::initializer_list<NSString*> domains = {
     88#if PLATFORM(IOS_FAMILY)
    11689        @"com.apple.Accessibility",
    117 #if PLATFORM(IOS_FAMILY)
    11890        @"com.apple.AdLib",
    119         @"com.apple.CFNetwork",
    120         @"com.apple.EmojiPreferences",
    121         @"com.apple.FontParser",
    122         @"com.apple.ImageIO",
    123         @"com.apple.InputModePreferences",
    124 #else
    125         @"com.apple.ATS",
    126         @"com.apple.CoreGraphics",
    127         @"com.apple.DownloadAssessment",
    128         @"com.apple.HIToolbox",
    129 #endif
    130         @"com.apple.LaunchServices",
    131 #if PLATFORM(IOS_FAMILY)
    132         @"com.apple.Metal",
    133         @"com.apple.MobileAsset",
    13491        @"com.apple.Preferences",
    13592        @"com.apple.SpeakSelection",
    13693        @"com.apple.UIKit",
    137         @"com.apple.VoiceOverTouch",
     94        @"com.apple.WebUI",
     95        @"com.apple.avfaudio",
     96        @"com.apple.itunesstored",
     97        @"com.apple.mediaremote",
     98        @"com.apple.preferences.sounds",
     99        @"com.apple.voiceservices",
     100        @"kCFPreferencesAnyApplication",
    138101#else
    139         @"com.apple.MultitouchSupport"
    140         @"com.apple.ServicesMenu.Services"
    141         @"com.apple.ViewBridge"
    142 #endif
    143         @"com.apple.WebFoundation",
    144 #if PLATFORM(IOS_FAMILY)
    145         @"com.apple.WebKit.WebContent",
    146         @"com.apple.WebUI",
    147         @"com.apple.airplay",
    148         @"com.apple.applejpeg",
    149         @"com.apple.audio.virtualaudio",
    150         @"com.apple.avfaudio",
    151 #endif
     102        @"com.apple.CoreGraphics",
     103        @"com.apple.HIToolbox",
     104        @"com.apple.ServicesMenu.Services",
     105        @"com.apple.ViewBridge",
    152106        @"com.apple.avfoundation",
    153         @"com.apple.avfoundation.frecents",
    154107        @"com.apple.avfoundation.videoperformancehud",
    155 #if PLATFORM(IOS_FAMILY)
    156         @"com.apple.avkit",
    157         @"com.apple.coreanimation",
    158         @"com.apple.coreaudio",
    159 #endif
    160         @"com.apple.coremedia",
    161 #if PLATFORM(IOS_FAMILY)
    162         @"com.apple.corevideo",
    163         @"com.apple.da",
    164         @"com.apple.hangtracer",
    165         @"com.apple.indigo",
    166         @"com.apple.iokit.IOMobileGraphicsFamily",
    167         @"com.apple.itunesstored",
    168         @"com.apple.keyboard",
    169 #else
    170         @"com.apple.crypto",
    171108        @"com.apple.driver.AppleBluetoothMultitouch.mouse",
    172109        @"com.apple.driver.AppleBluetoothMultitouch.trackpad",
    173         @"com.apple.driver.AppleHIDMouse"
    174 #endif
    175         @"com.apple.lookup.shared",
    176110        @"com.apple.mediaaccessibility",
    177 #if PLATFORM(IOS_FAMILY)
    178         @"com.apple.mediaaccessibility.public",
    179         @"com.apple.mediaremote",
    180         @"com.apple.mobileipod",
    181         @"com.apple.mt",
    182 #else
    183         @"com.apple.networkConnect"
    184 #endif
    185         @"com.apple.opengl",
    186 #if PLATFORM(IOS_FAMILY)
    187         @"com.apple.preferences.sounds",
    188         @"com.apple.security",
    189         @"com.apple.voiceservices",
    190         @"com.apple.voiceservices.logging",
    191 #else
    192111        @"com.apple.speech.voice.prefs",
    193         @"com.apple.systemsound",
    194112        @"com.apple.universalaccess",
    195         @"com.nvidia.OpenGL",
    196         @"edu.mit.Kerberos",
    197 #endif
    198113        @"kCFPreferencesAnyApplication",
    199 #if !PLATFORM(IOS_FAMILY)
    200         @"pbs",
    201114#endif
    202115    };
  • trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm

    r258915 r258949  
    174174
    175175    setLegacyCustomProtocolManagerClient(makeUnique<LegacyCustomProtocolManagerClient>());
    176 
    177 #if ENABLE(CFPREFS_DIRECT_MODE)
    178     [WKPreferenceObserver swizzleRegisterDefaults];
    179     dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), ^{
    180         // Start observing preference changes.
    181         [WKPreferenceObserver sharedInstance];
    182     });
    183 #endif
    184176}
    185177
     
    612604#endif
    613605
     606#if ENABLE(CFPREFS_DIRECT_MODE)
     607void WebProcessPool::startObservingPreferenceChanges()
     608{
     609    static dispatch_once_t onceToken;
     610    dispatch_once(&onceToken, ^{
     611        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
     612            // Start observing preference changes.
     613            [WKPreferenceObserver sharedInstance];
     614        });
     615    });
     616}
     617#endif
     618
    614619void WebProcessPool::registerNotificationObservers()
    615620{
     
    656661
    657662    m_activationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationDidBecomeActiveNotification object:NSApp queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) {
     663#if ENABLE(CFPREFS_DIRECT_MODE)
     664        startObservingPreferenceChanges();
     665#endif
    658666        setApplicationIsActive(true);
    659667    }];
     
    677685        }
    678686    }];
     687#if ENABLE(CFPREFS_DIRECT_MODE)
     688    m_activationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:@"UIApplicationDidBecomeActiveNotification" object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) {
     689        startObservingPreferenceChanges();
     690    }];
     691#endif
    679692#endif // !PLATFORM(IOS_FAMILY)
    680693}
     
    692705    [[NSNotificationCenter defaultCenter] removeObserver:m_scrollerStyleNotificationObserver.get()];
    693706#endif
    694     [[NSNotificationCenter defaultCenter] removeObserver:m_activationObserver.get()];
    695707    [[NSNotificationCenter defaultCenter] removeObserver:m_deactivationObserver.get()];
    696708#elif !PLATFORM(MACCATALYST)
     
    702714#endif // PLATFORM(IOS)
    703715    [[NSNotificationCenter defaultCenter] removeObserver:m_accessibilityEnabledObserver.get()];
     716    [[NSNotificationCenter defaultCenter] removeObserver:m_activationObserver.get()];
    704717#endif // !PLATFORM(IOS_FAMILY)
    705718}
  • trunk/Source/WebKit/UIProcess/WebProcessPool.h

    r258734 r258949  
    612612#endif
    613613
     614#if ENABLE(CFPREFS_DIRECT_MODE)
     615    void startObservingPreferenceChanges();
     616#endif
     617
    614618    Ref<API::ProcessPoolConfiguration> m_configuration;
    615619
     
    692696    RetainPtr<NSObject> m_scrollerStyleNotificationObserver;
    693697#endif
    694     RetainPtr<NSObject> m_activationObserver;
    695698    RetainPtr<NSObject> m_deactivationObserver;
    696699
     
    700703
    701704#if PLATFORM(COCOA)
     705    RetainPtr<NSObject> m_activationObserver;
    702706    RetainPtr<NSObject> m_accessibilityEnabledObserver;
    703707#endif
     
    803807#endif
    804808    bool m_useSeparateServiceWorkerProcess { false };
    805 
    806 #if PLATFORM(COCOA)
    807     RetainPtr<WKPreferenceObserver> m_preferenceObserver;
    808 #endif
    809809};
    810810
  • trunk/Source/WebKit/WebProcess/com.apple.WebProcess.sb.in

    r258915 r258949  
    678678#endif
    679679    (global-name "com.apple.PowerManagement.control")
    680     (global-name "com.apple.cfprefsd.daemon")
    681680    (global-name "com.apple.coreservices.launchservicesd")
    682681    (global-name "com.apple.lsd.mapdb")
  • trunk/Tools/ChangeLog

    r258947 r258949  
     12020-03-24  Per Arne Vollan  <pvollan@apple.com>
     2
     3        [Cocoa] Fix launch time regression with CF prefs direct mode enabled
     4        https://bugs.webkit.org/show_bug.cgi?id=209244
     5
     6        Reviewed by Darin Adler.
     7
     8        * TestWebKitAPI/Tests/WebKit/PreferenceChanges.mm:
     9        (TEST):
     10        (sharedInstanceMethodOverride):
     11
    1122020-03-24  Jonathan Bedard  <jbedard@apple.com>
    213
  • trunk/Tools/TestWebKitAPI/Tests/WebKit/PreferenceChanges.mm

    r258495 r258949  
    3232#import <WebKit/PreferenceObserver.h>
    3333
     34#import <wtf/ObjCRuntimeExtras.h>
     35
    3436static bool done = false;
    3537
     
    4547@end
    4648
     49static const CFStringRef testKey = CFSTR("testkey");
     50static const CFStringRef testDomain = CFSTR("kCFPreferencesAnyApplication");
     51
    4752TEST(WebKit, PreferenceObserver)
    4853{
    4954    done = false;
    5055
    51     CFPreferencesSetAppValue(CFSTR("testkey"), CFSTR("1"), CFSTR("com.apple.coremedia"));
     56    CFPreferencesSetAppValue(testKey, CFSTR("1"), testDomain);
    5257
    5358    auto observer = adoptNS([[WKTestPreferenceObserver alloc] init]);
    5459
    55     CFPreferencesSetAppValue(CFSTR("testkey"), CFSTR("2"), CFSTR("com.apple.coremedia"));
     60    CFPreferencesSetAppValue(testKey, CFSTR("2"), testDomain);
    5661
    5762    TestWebKitAPI::Util::run(&done);
     
    6469    NSArray *array = @[@1, @2, @3];
    6570
    66     auto userDefaults = adoptNS([[NSUserDefaults alloc] initWithSuiteName:@"com.apple.coremedia"]);
    67     [userDefaults.get() setObject:array forKey:@"testkey"];
     71    auto userDefaults = adoptNS([[NSUserDefaults alloc] initWithSuiteName:(NSString *)testDomain]);
     72    [userDefaults.get() setObject:array forKey:(NSString *)testKey];
    6873
    6974    auto observer = adoptNS([[WKTestPreferenceObserver alloc] init]);
    7075
    7176    NSArray *changedArray = @[@3, @2, @1];
    72     [userDefaults.get() setObject:changedArray forKey:@"testkey"];
     77    [userDefaults.get() setObject:changedArray forKey:(NSString *)testKey];
    7378
    7479    TestWebKitAPI::Util::run(&done);
     
    7782TEST(WebKit, PreferenceChanges)
    7883{
    79     CFPreferencesSetAppValue(CFSTR("testkey"), CFSTR("1"), CFSTR("com.apple.coremedia"));
    80 
    81     EXPECT_EQ(1, CFPreferencesGetAppIntegerValue(CFSTR("testkey"), CFSTR("com.apple.coremedia"), nullptr));
    82 
    83     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    84     WKRetainPtr<WKContextRef> context = adoptWK(TestWebKitAPI::Util::createContextForInjectedBundleTest("InternalsInjectedBundleTest"));
    85     configuration.get().processPool = (WKProcessPool *)context.get();
    86     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
    87 
    88     auto preferenceValue = [&] {
    89         return [webView stringByEvaluatingJavaScript:@"window.internals.readPreferenceInteger(\"com.apple.coremedia\", \"testkey\")"].intValue;
     84    CFPreferencesSetAppValue(testKey, CFSTR("1"), testDomain);
     85
     86    EXPECT_EQ(1, CFPreferencesGetAppIntegerValue(testKey, testDomain, nullptr));
     87
     88    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     89    WKRetainPtr<WKContextRef> context = adoptWK(TestWebKitAPI::Util::createContextForInjectedBundleTest("InternalsInjectedBundleTest"));
     90    configuration.get().processPool = (WKProcessPool *)context.get();
     91    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
     92
     93    auto preferenceValue = [&] {
     94        NSString *js = [NSString stringWithFormat:@"window.internals.readPreferenceInteger(\"%@\",\"%@\")", (NSString *)testDomain, (NSString *)testKey];
     95        return [webView stringByEvaluatingJavaScript:js].intValue;
    9096    };
    9197
    9298    EXPECT_EQ(preferenceValue(), 1);
    9399
    94     CFPreferencesSetAppValue(CFSTR("testkey"), CFSTR("2"), CFSTR("com.apple.coremedia"));
     100    CFPreferencesSetAppValue(testKey, CFSTR("2"), testDomain);
    95101
    96102    EXPECT_EQ(preferenceValue(), 2);
     
    101107    NSArray *array = @[@1, @2, @3];
    102108
    103     auto userDefaults = adoptNS([[NSUserDefaults alloc] initWithSuiteName:@"com.apple.coremedia"]);
    104     [userDefaults.get() setObject:array forKey:@"testkey"];
    105 
    106     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    107     WKRetainPtr<WKContextRef> context = adoptWK(TestWebKitAPI::Util::createContextForInjectedBundleTest("InternalsInjectedBundleTest"));
    108     configuration.get().processPool = (WKProcessPool *)context.get();
    109     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
    110 
    111     auto preferenceValue = [&] {
    112         return [webView stringByEvaluatingJavaScript:@"window.internals.encodedPreferenceValue(\"com.apple.coremedia\", \"testkey\")"];
     109    auto userDefaults = adoptNS([[NSUserDefaults alloc] initWithSuiteName:(NSString *)testDomain]);
     110    [userDefaults.get() setObject:array forKey:(NSString *)testKey];
     111
     112    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     113    WKRetainPtr<WKContextRef> context = adoptWK(TestWebKitAPI::Util::createContextForInjectedBundleTest("InternalsInjectedBundleTest"));
     114    configuration.get().processPool = (WKProcessPool *)context.get();
     115    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
     116
     117    auto preferenceValue = [&] {
     118        NSString *js = [NSString stringWithFormat:@"window.internals.encodedPreferenceValue(\"%@\",\"%@\")", (NSString *)testDomain, (NSString *)testKey];
     119        return [webView stringByEvaluatingJavaScript:js];
    113120    };
    114121
     
    116123
    117124    NSArray *changedArray = @[@3, @2, @1];
    118     [userDefaults.get() setObject:changedArray forKey:@"testkey"];
     125    [userDefaults.get() setObject:changedArray forKey:(NSString *)testKey];
    119126
    120127    auto encodedString = preferenceValue();
     
    135142    };
    136143
    137     auto userDefaults = adoptNS([[NSUserDefaults alloc] initWithSuiteName:@"com.apple.coremedia"]);
    138     [userDefaults.get() setObject:dict forKey:@"testkey"];
    139 
    140     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    141     WKRetainPtr<WKContextRef> context = adoptWK(TestWebKitAPI::Util::createContextForInjectedBundleTest("InternalsInjectedBundleTest"));
    142     configuration.get().processPool = (WKProcessPool *)context.get();
    143     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
    144 
    145     auto preferenceValue = [&] {
    146         return [webView stringByEvaluatingJavaScript:@"window.internals.encodedPreferenceValue(\"com.apple.coremedia\", \"testkey\")"];
     144    auto userDefaults = adoptNS([[NSUserDefaults alloc] initWithSuiteName:(NSString *)testDomain]);
     145    [userDefaults.get() setObject:dict forKey:(NSString *)testKey];
     146
     147    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     148    WKRetainPtr<WKContextRef> context = adoptWK(TestWebKitAPI::Util::createContextForInjectedBundleTest("InternalsInjectedBundleTest"));
     149    configuration.get().processPool = (WKProcessPool *)context.get();
     150    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
     151
     152    auto preferenceValue = [&] {
     153        NSString *js = [NSString stringWithFormat:@"window.internals.encodedPreferenceValue(\"%@\",\"%@\")", (NSString *)testDomain, (NSString *)testKey];
     154        return [webView stringByEvaluatingJavaScript:js];
    147155    };
    148156
     
    154162        @"c" : @3,
    155163    };
    156     [userDefaults.get() setObject:changedDict forKey:@"testkey"];
     164    [userDefaults.get() setObject:changedDict forKey:(NSString *)testKey];
    157165
    158166    auto encodedString = preferenceValue();
     
    170178    NSData *data = [NSData dataWithBytes:"abc" length:3];
    171179
    172     auto userDefaults = adoptNS([[NSUserDefaults alloc] initWithSuiteName:@"com.apple.coremedia"]);
    173     [userDefaults.get() setObject:data forKey:@"testkey"];
    174 
    175     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    176     WKRetainPtr<WKContextRef> context = adoptWK(TestWebKitAPI::Util::createContextForInjectedBundleTest("InternalsInjectedBundleTest"));
    177     configuration.get().processPool = (WKProcessPool *)context.get();
    178     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
    179 
    180     auto preferenceValue = [&] {
    181         return [webView stringByEvaluatingJavaScript:@"window.internals.encodedPreferenceValue(\"com.apple.coremedia\", \"testkey\")"];
     180    auto userDefaults = adoptNS([[NSUserDefaults alloc] initWithSuiteName:(NSString *)testDomain]);
     181    [userDefaults.get() setObject:data forKey:(NSString *)testKey];
     182
     183    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     184    WKRetainPtr<WKContextRef> context = adoptWK(TestWebKitAPI::Util::createContextForInjectedBundleTest("InternalsInjectedBundleTest"));
     185    configuration.get().processPool = (WKProcessPool *)context.get();
     186    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
     187
     188    auto preferenceValue = [&] {
     189        NSString *js = [NSString stringWithFormat:@"window.internals.encodedPreferenceValue(\"%@\",\"%@\")", (NSString *)testDomain, (NSString *)testKey];
     190        return [webView stringByEvaluatingJavaScript:js];
    182191    };
    183192
     
    185194
    186195    NSData *changedData = [NSData dataWithBytes:"abcd" length:4];
    187     [userDefaults.get() setObject:changedData forKey:@"testkey"];
     196    [userDefaults.get() setObject:changedData forKey:(NSString *)testKey];
    188197
    189198    auto encodedString = preferenceValue();
     
    201210    NSDate *date = [NSDate dateWithTimeIntervalSinceNow:0];
    202211
    203     auto userDefaults = adoptNS([[NSUserDefaults alloc] initWithSuiteName:@"com.apple.coremedia"]);
    204     [userDefaults.get() setObject:date forKey:@"testkey"];
    205 
    206     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    207     WKRetainPtr<WKContextRef> context = adoptWK(TestWebKitAPI::Util::createContextForInjectedBundleTest("InternalsInjectedBundleTest"));
    208     configuration.get().processPool = (WKProcessPool *)context.get();
    209     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
    210 
    211     auto preferenceValue = [&] {
    212         return [webView stringByEvaluatingJavaScript:@"window.internals.encodedPreferenceValue(\"com.apple.coremedia\", \"testkey\")"];
     212    auto userDefaults = adoptNS([[NSUserDefaults alloc] initWithSuiteName:(NSString *)testDomain]);
     213    [userDefaults.get() setObject:date forKey:(NSString *)testKey];
     214
     215    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     216    WKRetainPtr<WKContextRef> context = adoptWK(TestWebKitAPI::Util::createContextForInjectedBundleTest("InternalsInjectedBundleTest"));
     217    configuration.get().processPool = (WKProcessPool *)context.get();
     218    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
     219
     220    auto preferenceValue = [&] {
     221        NSString *js = [NSString stringWithFormat:@"window.internals.encodedPreferenceValue(\"%@\",\"%@\")", (NSString *)testDomain, (NSString *)testKey];
     222        return [webView stringByEvaluatingJavaScript:js];
    213223    };
    214224
     
    216226
    217227    NSDate *changedDate = [NSDate dateWithTimeIntervalSinceNow:10];
    218     [userDefaults.get() setObject:changedDate forKey:@"testkey"];
     228    [userDefaults.get() setObject:changedDate forKey:(NSString *)testKey];
    219229
    220230    auto encodedString = preferenceValue();
     
    228238}
    229239
     240static IMP sharedInstanceMethodOriginal = nil;
     241
     242static WKPreferenceObserver *sharedInstanceMethodOverride(id self, SEL selector)
     243{
     244    done = true;
     245    return wtfCallIMP<WKPreferenceObserver *>(sharedInstanceMethodOriginal, self, selector);
     246}
     247
     248TEST(WebKit, PreferenceObserverStartedOnActivation)
     249{
     250    done = false;
     251    Method sharedInstanceMethod = class_getClassMethod(objc_getClass("WKPreferenceObserver"), @selector(sharedInstance));
     252    ASSERT(sharedInstanceMethod);
     253    sharedInstanceMethodOriginal = method_setImplementation(sharedInstanceMethod, (IMP)sharedInstanceMethodOverride);
     254    ASSERT(sharedInstanceMethodOriginal);
     255
     256    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
     257    WKRetainPtr<WKContextRef> context = adoptWK(TestWebKitAPI::Util::createContextForInjectedBundleTest("InternalsInjectedBundleTest"));
     258    configuration.get().processPool = (WKProcessPool *)context.get();
     259    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 300, 300) configuration:configuration.get() addToWindow:YES]);
     260
     261    [webView synchronouslyLoadTestPageNamed:@"simple"];
     262
     263    [[NSNotificationCenter defaultCenter] postNotificationName:NSApplicationDidBecomeActiveNotification object:NSApp userInfo:nil];
     264
     265    TestWebKitAPI::Util::run(&done);
     266}
     267
    230268#endif // WK_HAVE_C_SPI
Note: See TracChangeset for help on using the changeset viewer.