mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +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',
|
'nsMacCharset.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if CONFIG['ENABLE_INTL_API']:
|
||||||
|
UNIFIED_SOURCES += ['OSPreferences_mac.cpp']
|
||||||
|
|
||||||
FINAL_LIBRARY = 'xul'
|
FINAL_LIBRARY = 'xul'
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
'..',
|
'..',
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
|
|
||||||
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
|
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
|
||||||
|
|
||||||
|
if CONFIG['ENABLE_INTL_API']:
|
||||||
|
SOURCES += ['OSPreferences.cpp']
|
||||||
|
|
||||||
toolkit = CONFIG['MOZ_WIDGET_TOOLKIT']
|
toolkit = CONFIG['MOZ_WIDGET_TOOLKIT']
|
||||||
|
|
||||||
if toolkit == 'windows':
|
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',
|
'TestLocaleService.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if CONFIG['ENABLE_INTL_API']:
|
||||||
|
UNIFIED_SOURCES += ['TestOSPreferences.cpp']
|
||||||
|
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
'/intl/locale',
|
'/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',
|
'nsPosixLocale.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if CONFIG['ENABLE_INTL_API']:
|
||||||
|
SOURCES += ['OSPreferences_unix.cpp']
|
||||||
|
|
||||||
if CONFIG['OS_TARGET'] == 'Android':
|
if CONFIG['OS_TARGET'] == 'Android':
|
||||||
SOURCES += [
|
SOURCES += [
|
||||||
'nsAndroidCharset.cpp',
|
'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',
|
'nsWinCharset.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if CONFIG['ENABLE_INTL_API']:
|
||||||
|
SOURCES += ['OSPreferences_win.cpp']
|
||||||
|
|
||||||
FINAL_LIBRARY = 'xul'
|
FINAL_LIBRARY = 'xul'
|
||||||
|
|
||||||
GENERATED_FILES = [
|
GENERATED_FILES = [
|
||||||
|
Loading…
Reference in New Issue
Block a user