RESOLVED FIXED 213214
Stop calling userPreferredLanguages() in the UIProcess
https://bugs.webkit.org/show_bug.cgi?id=213214
Summary Stop calling userPreferredLanguages() in the UIProcess
Chris Dumez
Reported 2020-06-15 14:26:04 PDT
Stop calling userPreferredLanguages() in the UIProcess since this can be slow and may keep the main thread busy. Nowadays, the WebProcess is able to call it by itself anyway. The sandbox is allowing it.
Attachments
Patch (8.65 KB, patch)
2020-06-15 14:28 PDT, Chris Dumez
no flags
Patch (11.58 KB, patch)
2020-06-15 17:06 PDT, Chris Dumez
no flags
Patch (11.66 KB, patch)
2020-06-15 17:10 PDT, Chris Dumez
no flags
Patch (11.31 KB, patch)
2020-06-16 08:29 PDT, Chris Dumez
no flags
Patch (2.11 KB, patch)
2020-06-16 10:10 PDT, Chris Dumez
no flags
Patch (2.32 KB, patch)
2020-06-16 10:22 PDT, Chris Dumez
no flags
Patch (2.38 KB, patch)
2020-06-16 10:24 PDT, Chris Dumez
no flags
Patch (2.35 KB, patch)
2020-06-16 10:35 PDT, Chris Dumez
no flags
Patch (2.39 KB, patch)
2020-06-16 10:37 PDT, Chris Dumez
no flags
Chris Dumez
Comment 1 2020-06-15 14:26:50 PDT
Chris Dumez
Comment 2 2020-06-15 14:28:34 PDT
Alexey Proskuryakov
Comment 3 2020-06-15 14:53:47 PDT
Comment on attachment 401938 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=401938&action=review > Source/WTF/ChangeLog:3 > + Stop calling userPreferredLanguages() in the UIProcess Does this work when the preference is not global? One can write NSUserDefaults for just the UI process bundle ID, or even from command line with -AppleLanguages option. It's not visible in this patch whether that goes in overrideLanguages already.
Chris Dumez
Comment 4 2020-06-15 14:58:17 PDT
Comment on attachment 401938 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=401938&action=review >> Source/WTF/ChangeLog:3 >> + Stop calling userPreferredLanguages() in the UIProcess > > Does this work when the preference is not global? One can write NSUserDefaults for just the UI process bundle ID, or even from command line with -AppleLanguages option. > > It's not visible in this patch whether that goes in overrideLanguages already. I do not expect any behavior change here. We merely call userPreferredLanguages() from the WebProcess instead of calling it in the UIProcess and sending it over IPC. userPreferredLanguages() just returns the overrides if set otherwise ends up calling CFLocaleCopyPreferredLanguages() on Cocoa ports. Calling CFLocaleCopyPreferredLanguages() from the WebProcess works (As confirmed by Per and validated locally) so there is no reason we need to call it from the UIProcess. I don't know what overrideLanguages is used for but my patch keeps getting them from the configuration and sending it over IPC. I did not change that.
Alexey Proskuryakov
Comment 5 2020-06-15 15:34:08 PDT
Comment on attachment 401938 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=401938&action=review >>> Source/WTF/ChangeLog:3 >>> + Stop calling userPreferredLanguages() in the UIProcess >> >> Does this work when the preference is not global? One can write NSUserDefaults for just the UI process bundle ID, or even from command line with -AppleLanguages option. >> >> It's not visible in this patch whether that goes in overrideLanguages already. > > I do not expect any behavior change here. We merely call userPreferredLanguages() from the WebProcess instead of calling it in the UIProcess and sending it over IPC. userPreferredLanguages() just returns the overrides if set otherwise ends up calling CFLocaleCopyPreferredLanguages() on Cocoa ports. Calling CFLocaleCopyPreferredLanguages() from the WebProcess works (As confirmed by Per and validated locally) so there is no reason we need to call it from the UIProcess. > > I don't know what overrideLanguages is used for but my patch keeps getting them from the configuration and sending it over IPC. I did not change that. We perform work to make CFLocale languages in WebProcess match UI process, but it's very much not obvious if they are going to return the same result always. I would object to landing this at the current level of understanding.
Chris Dumez
Comment 6 2020-06-15 15:59:13 PDT
(In reply to Alexey Proskuryakov from comment #5) > Comment on attachment 401938 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=401938&action=review > > >>> Source/WTF/ChangeLog:3 > >>> + Stop calling userPreferredLanguages() in the UIProcess > >> > >> Does this work when the preference is not global? One can write NSUserDefaults for just the UI process bundle ID, or even from command line with -AppleLanguages option. > >> > >> It's not visible in this patch whether that goes in overrideLanguages already. > > > > I do not expect any behavior change here. We merely call userPreferredLanguages() from the WebProcess instead of calling it in the UIProcess and sending it over IPC. userPreferredLanguages() just returns the overrides if set otherwise ends up calling CFLocaleCopyPreferredLanguages() on Cocoa ports. Calling CFLocaleCopyPreferredLanguages() from the WebProcess works (As confirmed by Per and validated locally) so there is no reason we need to call it from the UIProcess. > > > > I don't know what overrideLanguages is used for but my patch keeps getting them from the configuration and sending it over IPC. I did not change that. > > We perform work to make CFLocale languages in WebProcess match UI process, > but it's very much not obvious if they are going to return the same result > always. I would object to landing this at the current level of understanding. I do not understand what you mean by "We perform work to make CFLocale languages in WebProcess match UI process". All this patch does is call CFLocaleCopyPreferredLanguages() from the WebProcess instead of the UIProcess (like it used to a while back). I change language in system Preferences on both macOS and iOS and navigator.languages returns the right languages.
Alexey Proskuryakov
Comment 7 2020-06-15 16:08:04 PDT
I explained it in the first comment why testing just the global defaults is insufficient. We need to make this work in all these situations: 1. AppleLanguages user default is different between WebContent and UI process. 2. Available localizations are different between WebContent and UI process. CFLocaleCopyPreferredLanguages takes both defaults and localizations into consideration. There is no "just" about moving it between processes.
Alexey Proskuryakov
Comment 8 2020-06-15 16:17:12 PDT
> like it used to a while back I'm not sure what exactly you mean by "a while back". Was that a recent change? Do you know which one?
Chris Dumez
Comment 9 2020-06-15 16:22:07 PDT
(In reply to Alexey Proskuryakov from comment #7) > I explained it in the first comment why testing just the global defaults is > insufficient. We need to make this work in all these situations: > > 1. AppleLanguages user default is different between WebContent and UI > process. > > 2. Available localizations are different between WebContent and UI process. > > CFLocaleCopyPreferredLanguages takes both defaults and localizations into > consideration. There is no "just" about moving it between processes. Ok, I think I am able to reproduce the issue you were concerned about. I did: dvdo defaults write com.apple.Safari AppleLanguages '("en-US", "fr-FR")' In the UIProcess, I see both but in the WebContent process I only see en-US. I did not know this was a supported mechanism to change the locale of Safari.
Chris Dumez
Comment 10 2020-06-15 16:26:48 PDT
(In reply to Chris Dumez from comment #9) > (In reply to Alexey Proskuryakov from comment #7) > > I explained it in the first comment why testing just the global defaults is > > insufficient. We need to make this work in all these situations: > > > > 1. AppleLanguages user default is different between WebContent and UI > > process. > > > > 2. Available localizations are different between WebContent and UI process. > > > > CFLocaleCopyPreferredLanguages takes both defaults and localizations into > > consideration. There is no "just" about moving it between processes. > > Ok, I think I am able to reproduce the issue you were concerned about. I did: > dvdo defaults write com.apple.Safari AppleLanguages '("en-US", "fr-FR")' > > In the UIProcess, I see both but in the WebContent process I only see en-US. > I did not know this was a supported mechanism to change the locale of Safari. There is code in XPCServiceMain.mm that tries to deal with AppleLanguages. Did not seem to work for me. Will try and figure out why.
Chris Dumez
Comment 11 2020-06-15 17:06:23 PDT
Chris Dumez
Comment 12 2020-06-15 17:07:09 PDT
(In reply to Chris Dumez from comment #11) > Created attachment 401958 [details] > Patch This iteration forwards AppleLanguages UserDefaults from the UIProcess to the WebContent process to keep it working.
Chris Dumez
Comment 13 2020-06-15 17:10:27 PDT
Alexey Proskuryakov
Comment 14 2020-06-15 18:02:16 PDT
I won't have time to think about this deeply soon, but given that you made these scenarios work, the patch must be OK.
Per Arne Vollan
Comment 15 2020-06-16 08:26:19 PDT
Comment on attachment 401959 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=401959&action=review R=me. After this patch, can the language related code in XPCServiceMain.mm be removed? > Source/WebKit/UIProcess/WebProcessPool.cpp:1085 > + userPreferredLanguages(); Is this call needed?
Chris Dumez
Comment 16 2020-06-16 08:27:28 PDT
Comment on attachment 401959 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=401959&action=review >> Source/WebKit/UIProcess/WebProcessPool.cpp:1085 >> + userPreferredLanguages(); > > Is this call needed? Hahah lol, I had added it for debugging purposes :) Will drop. Thanks for catching.
Chris Dumez
Comment 17 2020-06-16 08:29:25 PDT
Chris Dumez
Comment 18 2020-06-16 08:30:08 PDT
Chris Dumez
Comment 19 2020-06-16 08:32:59 PDT
(In reply to Per Arne Vollan from comment #15) > Comment on attachment 401959 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=401959&action=review > > R=me. After this patch, can the language related code in XPCServiceMain.mm > be removed? No, my patch actually relies on the code in XPCServiceMain to forward the AppleLanguages UserDefaults from the UIProcess to the WebProcess.
Darin Adler
Comment 20 2020-06-16 09:38:27 PDT
Comment on attachment 401959 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=401959&action=review > Source/WebKit/UIProcess/Cocoa/WebProcessProxyCocoa.mm:261 > + Vector<String> overrideLanguages; > + overrideLanguages.reserveInitialCapacity([languages count]); > + for (NSString *language in languages) > + overrideLanguages.uncheckedAppend(language); > + return overrideLanguages; The makeNSArray function in VectorCocoa.h does this for you; you don’t have to write it out.
Chris Dumez
Comment 21 2020-06-16 10:08:15 PDT
(In reply to Darin Adler from comment #20) > Comment on attachment 401959 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=401959&action=review > > > Source/WebKit/UIProcess/Cocoa/WebProcessProxyCocoa.mm:261 > > + Vector<String> overrideLanguages; > > + overrideLanguages.reserveInitialCapacity([languages count]); > > + for (NSString *language in languages) > > + overrideLanguages.uncheckedAppend(language); > > + return overrideLanguages; > > The makeNSArray function in VectorCocoa.h does this for you; you don’t have > to write it out. I assume you mean makeVector<String>(). It looks great, I did not know it existed. I will fix shortly, thanks.
Chris Dumez
Comment 22 2020-06-16 10:10:50 PDT
Reopening to attach new patch.
Chris Dumez
Comment 23 2020-06-16 10:10:51 PDT
Darin Adler
Comment 24 2020-06-16 10:14:08 PDT
Comment on attachment 402017 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=402017&action=review > Source/WebKit/UIProcess/Cocoa/WebProcessProxyCocoa.mm:253 > NeverDestroyed<Vector<String>> overrideLanguages = []() { Just noticed that "static" is missing here, so we are probably leaking vectors. > Source/WebKit/UIProcess/Cocoa/WebProcessProxyCocoa.mm:255 > NSArray *languages = [[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"]; > - if (!languages) > - return Vector<WTF::String> { }; > - > - Vector<String> overrideLanguages; > - overrideLanguages.reserveInitialCapacity([languages count]); > - for (NSString *language in languages) > - overrideLanguages.uncheckedAppend(language); > - return overrideLanguages; > + return makeVector<String>(languages); Could go one step further and make this one line.
Darin Adler
Comment 25 2020-06-16 10:16:11 PDT
Comment on attachment 402017 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=402017&action=review >> Source/WebKit/UIProcess/Cocoa/WebProcessProxyCocoa.mm:253 >> NeverDestroyed<Vector<String>> overrideLanguages = []() { > > Just noticed that "static" is missing here, so we are probably leaking vectors. Should probably be static const NeverDestroyed.
Chris Dumez
Comment 26 2020-06-16 10:22:44 PDT
Chris Dumez
Comment 27 2020-06-16 10:24:01 PDT
Darin Adler
Comment 28 2020-06-16 10:34:23 PDT
Comment on attachment 402019 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=402019&action=review > Source/WebKit/UIProcess/Cocoa/WebProcessProxyCocoa.mm:255 > + static const NeverDestroyed<Vector<String>> overrideLanguages = []() { > + return makeVector<String>([[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"]); > }(); Oh, don’t even need a lambda now!
Chris Dumez
Comment 29 2020-06-16 10:35:59 PDT
Darin Adler
Comment 30 2020-06-16 10:36:28 PDT
Comment on attachment 402019 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=402019&action=review > Source/WebKit/UIProcess/Cocoa/WebProcessProxyCocoa.mm:256 > return overrideLanguages.get(); Not sure we need to write the get() here; I think it works without it.
Chris Dumez
Comment 31 2020-06-16 10:36:29 PDT
Comment on attachment 402020 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=402020&action=review > Source/WebKit/UIProcess/Cocoa/WebProcessProxyCocoa.mm:253 > + static const NeverDestroyed<Vector<String>> overrideLanguages = makeVector<String>([[NSUserDefaults standardUserDefaults] valueForKey:@"AppleLanguages"]); Well, that is much more concise :)
Chris Dumez
Comment 32 2020-06-16 10:37:36 PDT
Chris Dumez
Comment 33 2020-06-16 10:37:58 PDT
(In reply to Darin Adler from comment #30) > Comment on attachment 402019 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=402019&action=review > > > Source/WebKit/UIProcess/Cocoa/WebProcessProxyCocoa.mm:256 > > return overrideLanguages.get(); > > Not sure we need to write the get() here; I think it works without it. It is indeed not needed, I dropped it.
EWS
Comment 34 2020-06-16 11:10:05 PDT
Committed r263100: <https://trac.webkit.org/changeset/263100> All reviewed patches have been landed. Closing bug and clearing flags on attachment 402021 [details].
Note You need to log in before you can comment on or make changes to this bug.