|
| 1 | +// Copyright (c) 2020 GitHub, Inc. |
| 2 | +// Use of this source code is governed by the MIT license that can be |
| 3 | +// found in the LICENSE file. |
| 4 | + |
| 5 | +#include "shell/common/language_util.h" |
| 6 | + |
| 7 | +#include <roapi.h> |
| 8 | +#include <windows.system.userprofile.h> |
| 9 | +#include <wrl.h> |
| 10 | + |
| 11 | +#include "base/strings/sys_string_conversions.h" |
| 12 | +#include "base/win/core_winrt_util.h" |
| 13 | +#include "base/win/i18n.h" |
| 14 | +#include "base/win/win_util.h" |
| 15 | +#include "base/win/windows_version.h" |
| 16 | + |
| 17 | +namespace electron { |
| 18 | + |
| 19 | +std::vector<std::string> GetPreferredLanguages() { |
| 20 | + std::vector<base::string16> languages16; |
| 21 | + |
| 22 | + // Attempt to use API available on Windows 10 or later, which |
| 23 | + // returns the full list of language preferences. |
| 24 | + if (!GetPreferredLanguagesUsingGlobalization(&languages16)) { |
| 25 | + base::win::i18n::GetThreadPreferredUILanguageList(&languages16); |
| 26 | + } |
| 27 | + |
| 28 | + std::vector<std::string> languages; |
| 29 | + for (const auto& language : languages16) { |
| 30 | + languages.push_back(base::SysWideToUTF8(language)); |
| 31 | + } |
| 32 | + return languages; |
| 33 | +} |
| 34 | + |
| 35 | +bool GetPreferredLanguagesUsingGlobalization( |
| 36 | + std::vector<base::string16>* languages) { |
| 37 | + if (base::win::GetVersion() < base::win::Version::WIN10) |
| 38 | + return false; |
| 39 | + if (!base::win::ResolveCoreWinRTDelayload() || |
| 40 | + !base::win::ScopedHString::ResolveCoreWinRTStringDelayload()) |
| 41 | + return false; |
| 42 | + |
| 43 | + base::win::ScopedHString guid = base::win::ScopedHString::Create( |
| 44 | + RuntimeClass_Windows_System_UserProfile_GlobalizationPreferences); |
| 45 | + Microsoft::WRL::ComPtr< |
| 46 | + ABI::Windows::System::UserProfile::IGlobalizationPreferencesStatics> |
| 47 | + prefs; |
| 48 | + |
| 49 | + HRESULT hr = |
| 50 | + base::win::RoGetActivationFactory(guid.get(), IID_PPV_ARGS(&prefs)); |
| 51 | + if (FAILED(hr)) |
| 52 | + return false; |
| 53 | + |
| 54 | + ABI::Windows::Foundation::Collections::IVectorView<HSTRING>* langs; |
| 55 | + hr = prefs->get_Languages(&langs); |
| 56 | + if (FAILED(hr)) |
| 57 | + return false; |
| 58 | + |
| 59 | + unsigned size; |
| 60 | + hr = langs->get_Size(&size); |
| 61 | + if (FAILED(hr)) |
| 62 | + return false; |
| 63 | + |
| 64 | + for (unsigned i = 0; i < size; ++i) { |
| 65 | + HSTRING hstr; |
| 66 | + hr = langs->GetAt(i, &hstr); |
| 67 | + if (SUCCEEDED(hr)) { |
| 68 | + base::WStringPiece str = base::win::ScopedHString(hstr).Get(); |
| 69 | + languages->emplace_back(str.data(), str.size()); |
| 70 | + } |
| 71 | + } |
| 72 | + |
| 73 | + return true; |
| 74 | +} |
| 75 | + |
| 76 | +} // namespace electron |
0 commit comments