mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1333184 - Introduce OSPreferences API. r=jfkthame
MozReview-Commit-ID: ALvLGtBmRgn --HG-- extra : rebase_source : fb237beec41e7b93eeac862be285074acfc36a77
This commit is contained in:
parent
2db2a32d40
commit
1aa7bc8b32
65
intl/locale/OSPreferences.cpp
Normal file
65
intl/locale/OSPreferences.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* This is a shared part of the OSPreferences API implementation.
|
||||
* It defines helper methods and public methods that are calling
|
||||
* platform-specific private methods.
|
||||
*/
|
||||
|
||||
#include "OSPreferences.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
|
||||
using namespace mozilla::intl;
|
||||
|
||||
mozilla::StaticAutoPtr<OSPreferences> OSPreferences::sInstance;
|
||||
|
||||
OSPreferences*
|
||||
OSPreferences::GetInstance()
|
||||
{
|
||||
if (!sInstance) {
|
||||
sInstance = new OSPreferences();
|
||||
ClearOnShutdown(&sInstance);
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
bool
|
||||
OSPreferences::GetSystemLocales(nsTArray<nsCString>& aRetVal)
|
||||
{
|
||||
bool status = true;
|
||||
if (mSystemLocales.IsEmpty()) {
|
||||
status = ReadSystemLocales(mSystemLocales);
|
||||
}
|
||||
aRetVal = mSystemLocales;
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should be called by every method of OSPreferences that
|
||||
* retrieves a locale id from external source.
|
||||
*
|
||||
* It attempts to retrieve as much of the locale ID as possible, cutting
|
||||
* out bits that are not understood (non-strict behavior of ICU).
|
||||
*
|
||||
* It returns true if the canonicalization was successful.
|
||||
*/
|
||||
bool
|
||||
OSPreferences::CanonicalizeLanguageTag(nsCString& aLoc)
|
||||
{
|
||||
char langTag[512];
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
int32_t langTagLen =
|
||||
uloc_toLanguageTag(aLoc.get(), langTag, sizeof(langTag) - 1, false, &status);
|
||||
|
||||
if (U_FAILURE(status)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aLoc.Assign(langTag, langTagLen);
|
||||
return true;
|
||||
}
|
92
intl/locale/OSPreferences.h
Normal file
92
intl/locale/OSPreferences.h
Normal file
@ -0,0 +1,92 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_intl_IntlOSPreferences_h__
|
||||
#define mozilla_intl_IntlOSPreferences_h__
|
||||
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "unicode/uloc.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace intl {
|
||||
|
||||
/**
|
||||
* OSPreferences API provides a set of methods for retrieving information from
|
||||
* the host environment on topics such as:
|
||||
* - Internationalization
|
||||
* - Localization
|
||||
* - Regional preferences
|
||||
*
|
||||
* The API is meant to remain as simple as possible, relaying information from
|
||||
* the host environment to the user without too much logic.
|
||||
*
|
||||
* Saying that, there are two exceptions to that paradigm.
|
||||
*
|
||||
* First one is normalization. We do intend to translate host environment
|
||||
* concepts to unified Intl/L10n vocabulary used by Mozilla.
|
||||
* That means that we will format locale IDs, timezone names, currencies etc.
|
||||
* into a chosen format.
|
||||
*
|
||||
* Second is caching. This API does cache values and where possible will
|
||||
* hook into the environment for some event-driven cache invalidation.
|
||||
*
|
||||
* This means that on platforms that do not support a mechanism to
|
||||
* notify apps about changes, new OS-level settings may not be reflected
|
||||
* in the app until it is relaunched.
|
||||
*/
|
||||
class OSPreferences
|
||||
{
|
||||
|
||||
public:
|
||||
static OSPreferences* GetInstance();
|
||||
|
||||
/**
|
||||
* Returns a list of locales used by the host environment.
|
||||
*
|
||||
* The result is a sorted list and we expect that the OS attempts to
|
||||
* use the top locale from the list for which it has data.
|
||||
*
|
||||
* Each element of the list is a valid locale ID that can be passed to ICU
|
||||
* and ECMA402 Intl APIs,
|
||||
* At the same time each element is a valid BCP47 language tag that can be
|
||||
* used for language negotiation.
|
||||
*
|
||||
* Example: ["en-US", "de", "pl", "sr-Cyrl", "zh-Hans-HK"]
|
||||
*
|
||||
* The return bool value indicates whether the function successfully
|
||||
* resolved at least one locale.
|
||||
*
|
||||
* Usage:
|
||||
* nsTArray<nsCString> systemLocales;
|
||||
* OSPreferences::GetInstance()->GetSystemLocales(systemLocales);
|
||||
*/
|
||||
bool GetSystemLocales(nsTArray<nsCString>& aRetVal);
|
||||
|
||||
protected:
|
||||
nsTArray<nsCString> mSystemLocales;
|
||||
|
||||
private:
|
||||
static StaticAutoPtr<OSPreferences> sInstance;
|
||||
|
||||
static bool CanonicalizeLanguageTag(nsCString& aLoc);
|
||||
|
||||
/**
|
||||
* This is a host environment specific method that will be implemented
|
||||
* separately for each platform.
|
||||
*
|
||||
* It is only called when the cache is empty or invalidated.
|
||||
*
|
||||
* The return value indicates whether the function successfully
|
||||
* resolved at least one locale.
|
||||
*/
|
||||
bool ReadSystemLocales(nsTArray<nsCString>& aRetVal);
|
||||
};
|
||||
|
||||
} // intl
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* mozilla_intl_IntlOSPreferences_h__ */
|
39
intl/locale/mac/OSPreferences_mac.cpp
Normal file
39
intl/locale/mac/OSPreferences_mac.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "OSPreferences.h"
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
using namespace mozilla::intl;
|
||||
|
||||
bool
|
||||
OSPreferences::ReadSystemLocales(nsTArray<nsCString>& aLocaleList)
|
||||
{
|
||||
MOZ_ASSERT(aLocaleList.IsEmpty());
|
||||
|
||||
// Get string representation of user's current locale
|
||||
CFLocaleRef userLocaleRef = ::CFLocaleCopyCurrent();
|
||||
CFStringRef userLocaleStr = ::CFLocaleGetIdentifier(userLocaleRef);
|
||||
|
||||
AutoTArray<UniChar, 32> buffer;
|
||||
int size = ::CFStringGetLength(userLocaleStr);
|
||||
|
||||
CFRange range = ::CFRangeMake(0, size);
|
||||
::CFStringGetCharacters(userLocaleStr, range, buffer.Elements());
|
||||
|
||||
// Convert the locale string to the format that Mozilla expects
|
||||
NS_LossyConvertUTF16toASCII locale(
|
||||
reinterpret_cast<const char16_t*>(buffer.Elements()), buffer.Length());
|
||||
|
||||
CFRelease(userLocaleRef);
|
||||
|
||||
if (CanonicalizeLanguageTag(locale)) {
|
||||
aLocaleList.AppendElement(locale);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
@ -9,6 +9,9 @@ UNIFIED_SOURCES += [
|
||||
'nsMacCharset.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['ENABLE_INTL_API']:
|
||||
UNIFIED_SOURCES += ['OSPreferences_mac.cpp']
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
LOCAL_INCLUDES += [
|
||||
'..',
|
||||
|
@ -6,6 +6,9 @@
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
|
||||
|
||||
if CONFIG['ENABLE_INTL_API']:
|
||||
SOURCES += ['OSPreferences.cpp']
|
||||
|
||||
toolkit = CONFIG['MOZ_WIDGET_TOOLKIT']
|
||||
|
||||
if toolkit == 'windows':
|
||||
|
24
intl/locale/tests/gtest/TestOSPreferences.cpp
Normal file
24
intl/locale/tests/gtest/TestOSPreferences.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "OSPreferences.h"
|
||||
|
||||
using namespace mozilla::intl;
|
||||
|
||||
/**
|
||||
* We test that on all platforms we test against (irrelevant of the tier),
|
||||
* we will be able to retrieve at least a single locale out of the system.
|
||||
*
|
||||
* In theory, that may not be true, but if we encounter such platform we should
|
||||
* decide how to handle this and special case and this test should make
|
||||
* it not happen without us noticing.
|
||||
*/
|
||||
TEST(Intl_Locale_OSPreferences, GetSystemLocales) {
|
||||
nsTArray<nsCString> systemLocales;
|
||||
ASSERT_TRUE(OSPreferences::GetInstance()->GetSystemLocales(systemLocales));
|
||||
|
||||
ASSERT_FALSE(systemLocales.IsEmpty());
|
||||
}
|
@ -8,6 +8,9 @@ UNIFIED_SOURCES += [
|
||||
'TestLocaleService.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['ENABLE_INTL_API']:
|
||||
UNIFIED_SOURCES += ['TestOSPreferences.cpp']
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/intl/locale',
|
||||
]
|
||||
|
23
intl/locale/unix/OSPreferences_unix.cpp
Normal file
23
intl/locale/unix/OSPreferences_unix.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "OSPreferences.h"
|
||||
|
||||
using namespace mozilla::intl;
|
||||
|
||||
bool
|
||||
OSPreferences::ReadSystemLocales(nsTArray<nsCString>& aLocaleList)
|
||||
{
|
||||
MOZ_ASSERT(aLocaleList.IsEmpty());
|
||||
|
||||
nsAutoCString defaultLang(uloc_getDefault());
|
||||
|
||||
if (CanonicalizeLanguageTag(defaultLang)) {
|
||||
aLocaleList.AppendElement(defaultLang);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
@ -9,6 +9,9 @@ SOURCES += [
|
||||
'nsPosixLocale.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['ENABLE_INTL_API']:
|
||||
SOURCES += ['OSPreferences_unix.cpp']
|
||||
|
||||
if CONFIG['OS_TARGET'] == 'Android':
|
||||
SOURCES += [
|
||||
'nsAndroidCharset.cpp',
|
||||
|
29
intl/locale/windows/OSPreferences_win.cpp
Normal file
29
intl/locale/windows/OSPreferences_win.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "OSPreferences.h"
|
||||
#include "nsWin32Locale.h"
|
||||
|
||||
using namespace mozilla::intl;
|
||||
|
||||
bool
|
||||
OSPreferences::ReadSystemLocales(nsTArray<nsCString>& aLocaleList)
|
||||
{
|
||||
MOZ_ASSERT(aLocaleList.IsEmpty());
|
||||
|
||||
nsAutoString locale;
|
||||
|
||||
LCID win_lcid = GetSystemDefaultLCID();
|
||||
nsWin32Locale::GetXPLocale(win_lcid, locale);
|
||||
|
||||
NS_LossyConvertUTF16toASCII loc(locale);
|
||||
|
||||
if (CanonicalizeLanguageTag(loc)) {
|
||||
aLocaleList.AppendElement(loc);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
@ -10,6 +10,9 @@ SOURCES += [
|
||||
'nsWinCharset.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['ENABLE_INTL_API']:
|
||||
SOURCES += ['OSPreferences_win.cpp']
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
GENERATED_FILES = [
|
||||
|
Loading…
Reference in New Issue
Block a user