Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 53 additions & 5 deletions shell/common/engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "flutter/common/settings.h"
#include "flutter/fml/eintr_wrapper.h"
#include "flutter/fml/file.h"
#include "flutter/fml/logging.h"
#include "flutter/fml/make_copyable.h"
#include "flutter/fml/paths.h"
#include "flutter/fml/trace_event.h"
Expand Down Expand Up @@ -325,14 +326,61 @@ bool Engine::HandleLocalizationPlatformMessage(
if (args == root.MemberEnd() || !args->value.IsArray())
return false;

const auto& language = args->value[0];
const auto& country = args->value[1];
const auto& languageBuffer = args->value[0];
const auto& countryBuffer = args->value[1];

if (!language.IsString() || !country.IsString())
if (!languageBuffer.IsString() || !countryBuffer.IsString())
return false;

return runtime_controller_->SetLocale(language.GetString(),
country.GetString());
std::string languageString = languageBuffer.GetString();
std::string countryString = countryBuffer.GetString();

// iOS only because only valid locales can be passed in from Android
#if defined(OS_IOS)
// TODO(garyq): Add support for script codes and derive script codes from
// unspecified locales.
//
// This is a hack.
//
// Manually handle iOS invalid lang-country combinations for Chinese.
// Locale resolution fails (picks first zh script) when Locales such as
// zh_Hant_US are specified because we do not support scriptcodes yet.
// This will prevent simplified scripts from being selected when Hanst
// is provided and vice-versa. The proper fix is to support scriptcodes
// in dart:ui Locale.
//
// This hack does not work for any non-chinese languages and is meant to
// resolve the issue for large languages without a breaking API change.
// The full fix is expected to take a non-trivial amount of time.
//
// This hack will not work if 'zh_HK' or 'zh' locales are not enabled.
//
// This hack will also make small dialects of Chinese harder to surface
// due to it blanket changing non-TW/HK countries into simplified CN.
// The trade off is we will not accidentally show traditional where
// simplified was requested and vice versa, which is a much larger scale
// issue.
const auto& scriptBuffer = args->value[2];
if (scriptBuffer.IsString()) {
std::string scriptString = scriptBuffer.GetString();
// Convert unspecified traditional to "HK"
if (languageString == "zh" && scriptString == "Hant" &&
countryString != "TW" && countryString != "HK") {
countryString = "HK";
} else if (languageString == "zh" && scriptString == "Hans") {
// Convert unspecified Hans to ""
countryString = "";
} else if (languageString == "zh" && countryString != "TW" &&
countryString != "HK") {
// Derive missing script code from country for Chinese.
// Prevents unspecified or zh_CN from resolving to traditional
countryString = "";
}
}

#endif

return runtime_controller_->SetLocale(languageString, countryString);
}

void Engine::HandleSettingsPlatformMessage(blink::PlatformMessage* message) {
Expand Down
2 changes: 1 addition & 1 deletion shell/platform/android/io/flutter/view/FlutterView.java
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ private void setUserSettings() {
}

private void setLocale(Locale locale) {
mFlutterLocalizationChannel.invokeMethod("setLocale", Arrays.asList(locale.getLanguage(), locale.getCountry()));
mFlutterLocalizationChannel.invokeMethod("setLocale", Arrays.asList(locale.getLanguage(), locale.getCountry(), locale.getScript()));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -894,8 +894,17 @@ - (void)onLocaleUpdated:(NSNotification*)notification {
NSLocale* currentLocale = [NSLocale currentLocale];
NSString* languageCode = [currentLocale objectForKey:NSLocaleLanguageCode];
NSString* countryCode = [currentLocale objectForKey:NSLocaleCountryCode];
if (languageCode && countryCode)
[_localizationChannel.get() invokeMethod:@"setLocale" arguments:@[ languageCode, countryCode ]];
NSString* scriptCode = [currentLocale objectForKey:NSLocaleScriptCode];
if (languageCode && countryCode) {
// Script code is not present when a language only has one script.
if (scriptCode) {
[_localizationChannel.get() invokeMethod:@"setLocale"
arguments:@[ languageCode, countryCode, scriptCode ]];
} else {
[_localizationChannel.get() invokeMethod:@"setLocale"
arguments:@[ languageCode, countryCode, @"" ]];
}
}
}

#pragma mark - Set user settings
Expand Down