provide set and get app language interfaces

Signed-off-by: sunyaozu <sunyaozu@huawei.com>
This commit is contained in:
sunyaozu 2023-11-07 17:21:44 +08:00
parent 891460fa54
commit 9119d224ae
6 changed files with 82 additions and 98 deletions

View File

@ -61,6 +61,7 @@
"init",
"ipc",
"napi",
"preferences",
"resource_management",
"samgr"
],

View File

@ -48,11 +48,13 @@ ohos_shared_library("preferred_language") {
"//foundation/systemabilitymgr/samgr/interfaces/innerkits/samgr_proxy/include/",
]
external_deps += [
"ability_runtime:app_context",
"bundle_framework:appexecfwk_base",
"bundle_framework:appexecfwk_core",
"c_utils:utils",
"hilog:libhilog",
"ipc:ipc_core",
"preferences:native_preferences",
"resource_management:global_resmgr",
"samgr:samgr_proxy",
]

View File

@ -14,6 +14,7 @@
*/
#ifdef SUPPORT_APP_PREFERRED_LANGUAGE
#include <regex>
#include "application_context.h"
#include "bundle_info.h"
#include "bundle_mgr_interface.h"
#include "hap_resource.h"
@ -36,6 +37,8 @@ const char *PreferredLanguage::RESOURCE_PATH_HEAD = "/data/accounts/account_0/ap
const char *PreferredLanguage::RESOURCE_PATH_TAILOR = "/assets/entry/resources.index";
const char *PreferredLanguage::RESOURCE_PATH_SPLITOR = "/";
const char *PreferredLanguage::PREFERRED_LANGUAGES = "persist.sys.preferredLanguages";
const char *PreferredLanguage::APP_LANGUAGE_KEY = "app_language";
const char *PreferredLanguage::I18N_PREFERENCES_FILE_NAME = "/i18n";
bool PreferredLanguage::AddPreferredLanguageExist(std::vector<std::string> &preferredLanguageList, int languageIdx,
int index, const std::string& language)
@ -200,108 +203,57 @@ std::string PreferredLanguage::GetFirstPreferredLanguage()
}
#ifdef SUPPORT_APP_PREFERRED_LANGUAGE
std::string PreferredLanguage::GetBundleName()
std::shared_ptr<NativePreferences::Preferences> PreferredLanguage::GetI18nAppPreferences()
{
auto systemAbilityManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (systemAbilityManager == nullptr) {
HiLog::Error(LABEL, "Failed to create system ability manager.");
return "";
std::shared_ptr<AbilityRuntime::ApplicationContext> appContext = AbilityRuntime::ApplicationContext::GetInstance();
std::string preferencesDirPath = appContext->GetPreferencesDir();
std::string i18nPreferencesFilePath = preferencesDirPath + I18N_PREFERENCES_FILE_NAME;
int status;
NativePreferences::Options options(i18nPreferencesFilePath);
std::shared_ptr<NativePreferences::Preferences> preferences =
NativePreferences::PreferencesHelper::GetPreferences(options, status);
if (status != 0) {
HiLog::Error(LABEL, "PreferredLanguage::GetAppPreferredLanguage get i18n app preferences failed.");
return nullptr;
}
auto bundleMgrSa = systemAbilityManager->GetSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
if (bundleMgrSa == nullptr) {
HiLog::Error(LABEL, "Failed to create bundle manager SA.");
return "";
}
auto bundleMgr = OHOS::iface_cast<AppExecFwk::IBundleMgr>(bundleMgrSa);
if (bundleMgr == nullptr) {
HiLog::Error(LABEL, "Failed to create bundle manager.");
return "";
}
AppExecFwk::BundleInfo bundleInfo;
bundleMgr->GetBundleInfoForSelf(0, bundleInfo);
return bundleInfo.name;
}
std::set<std::string> PreferredLanguage::GetResources()
{
std::string bundleName = GetBundleName();
const std::string resourcePath = RESOURCE_PATH_HEAD + bundleName + RESOURCE_PATH_SPLITOR + bundleName +
RESOURCE_PATH_TAILOR;
const OHOS::Global::Resource::HapResource *resource =
OHOS::Global::Resource::HapResource::LoadFromIndex(resourcePath.c_str(), nullptr);
const std::vector<std::string> qualifiers = resource->GetQualifiers();
std::set<std::string> result;
std::regex languagePattern("type:0.*str:([a-z]{2})");
std::regex countryPattern("type:1.*str:([A-Z]{2})");
for (size_t i = 0; i < qualifiers.size(); i++) {
std::smatch match;
bool found = regex_search(qualifiers[i], match, languagePattern);
if (!found) {
continue;
}
std::string locale = match.str(1);
found = regex_search(qualifiers[i], match, countryPattern);
if (found) {
locale += "-";
locale += match.str(1);
}
result.insert(locale);
}
return result;
}
bool PreferredLanguage::IsMatched(const std::string& preferred, const std::string& resource)
{
LocaleInfo preferredLocaleInfo(preferred);
LocaleInfo resourceLocaleInfo(resource);
if (preferred == resource) {
return true;
}
if (preferredLocaleInfo.GetLanguage() != resourceLocaleInfo.GetLanguage()) {
return false;
}
LocaleInfo maximizedResourceLocale(resourceLocaleInfo.Maximize());
std::string resourceScript = maximizedResourceLocale.GetScript();
if (resourceScript == "") {
std::string resourceCountry = maximizedResourceLocale.GetRegion();
if (resourceCountry == "") {
return true;
}
std::string preferredCountry = preferredLocaleInfo.GetRegion();
if (resourceCountry == preferredCountry) {
return true;
}
return false;
}
LocaleInfo maximizedPreferredLocale(preferredLocaleInfo.Maximize());
std::string preferredScript = maximizedResourceLocale.GetScript();
if (resourceScript == preferredScript) {
return true;
}
return false;
return preferences;
}
std::string PreferredLanguage::GetAppPreferredLanguage()
{
std::vector<std::string> preferredLanguageList = GetPreferredLanguageList();
std::set<std::string> resources = GetResources();
int minmumMatchedIdx = -1;
for (size_t i = 0; i < preferredLanguageList.size(); i++) {
for (std::set<std::string>::iterator it = resources.begin(); it != resources.end(); ++it) {
std::string preferredLanguage = preferredLanguageList[i];
if (preferredLanguage == "en-Qaag") {
preferredLanguage = "en-Latn";
}
if (IsMatched(preferredLanguage, *it)) {
minmumMatchedIdx = (int)i;
break;
}
}
std::shared_ptr<NativePreferences::Preferences> preferences = GetI18nAppPreferences();
if (preferences == nullptr) {
HiLog::Error(LABEL,
"PreferredLanguage::GetAppPreferredLanguage get i18n preferences failed, return system language.");
return LocaleConfig::GetSystemLanguage();
}
if (minmumMatchedIdx != -1) {
return preferredLanguageList[minmumMatchedIdx];
std::string res = preferences->GetString(PreferredLanguage::APP_LANGUAGE_KEY, "");
if (res.length() == 0) {
HiLog::Info(LABEL,
"PreferredLanguage::GetAppPreferredLanguage app language is empty, return system language.");
return LocaleConfig::GetSystemLanguage();
}
return preferredLanguageList[0];
return res;
}
void PreferredLanguage::SetAppPreferredLanguage(const std::string &language, I18nErrorCode &errCode)
{
std::shared_ptr<AbilityRuntime::ApplicationContext> appContext = AbilityRuntime::ApplicationContext::GetInstance();
appContext->SetLanguage(language);
std::shared_ptr<NativePreferences::Preferences> preferences = GetI18nAppPreferences();
if (preferences == nullptr) {
errCode = I18nErrorCode::FAILED;
HiLog::Error(LABEL, "PreferredLanguage::SetAppPreferredLanguage get i18n preferences failed.");
return;
}
int32_t status = preferences->PutString(PreferredLanguage::APP_LANGUAGE_KEY, language);
if (status != 0) {
errCode = I18nErrorCode::FAILED;
HiLog::Error(LABEL,
"PreferredLanguage::SetAppPreferredLanguage set app language to i18n preferences failed.");
return;
}
preferences->Flush();
}
#endif

View File

@ -11,6 +11,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import("//base/global/i18n/i18n.gni")
import("//build/ohos.gni")
group("build_module") {
@ -92,6 +93,9 @@ ohos_shared_library("i18n") {
"hilog:libhilog",
"napi:ace_napi",
]
if (i18n_support_app_preferred_language) {
defines = [ "SUPPORT_APP_PREFERRED_LANGUAGE" ]
}
relative_install_dir = "module"
subsystem_name = "global"
part_name = "i18n"

View File

@ -324,7 +324,13 @@ napi_value I18nSystemAddon::SetAppPreferredLanguage(napi_env env, napi_callback_
ErrorUtil::NapiThrow(env, I18N_NOT_VALID, true);
return nullptr;
}
// Do something next
#ifdef SUPPORT_APP_PREFERRED_LANGUAGE
I18nErrorCode errCode = I18nErrorCode::SUCCESS;
PreferredLanguage::SetAppPreferredLanguage(localeTag, errCode);
if (errCode != I18nErrorCode::SUCCESS) {
HiLog::Error(LABEL, "SetAppPreferredLanguage: set app language to i18n app preferences failed.");
}
#endif
return nullptr;
}

View File

@ -19,6 +19,9 @@
#include <string>
#include <vector>
#include "i18n_types.h"
#ifdef SUPPORT_APP_PREFERRED_LANGUAGE
#include "preferences_helper.h"
#endif
namespace OHOS {
namespace Global {
@ -30,7 +33,23 @@ public:
static std::vector<std::string> GetPreferredLanguageList();
static std::string GetFirstPreferredLanguage();
#ifdef SUPPORT_APP_PREFERRED_LANGUAGE
/**
* @brief Get App Language.
* Get the app language from app preferences data which saved by SetAppPreferredLanguage method.
*
* @return std::string return current app language.
*/
static std::string GetAppPreferredLanguage();
/**
* @brief Set App Language.
* The application interface will be refreshed in real time after call this method. And the language will be saved
* to app preferences data which will be used the next time the application starts.
*
* @param language language to be set.
* @param errCode Indicates whether the setting was successful; errCode == I18nErrorCode::SUCCESS means successful.
*/
static void SetAppPreferredLanguage(const std::string &language, I18nErrorCode &errCode);
#endif
static std::string GetPreferredLocale();
@ -43,14 +62,14 @@ private:
static bool IsValidTag(const std::string &tag);
static void Split(const std::string &src, const std::string &sep, std::vector<std::string> &dest);
#ifdef SUPPORT_APP_PREFERRED_LANGUAGE
static std::string GetBundleName();
static std::set<std::string> GetResources();
static bool IsMatched(const std::string& preferred, const std::string& resource);
static std::shared_ptr<NativePreferences::Preferences> GetI18nAppPreferences();
#endif
static const char *RESOURCE_PATH_HEAD;
static const char *RESOURCE_PATH_TAILOR;
static const char *RESOURCE_PATH_SPLITOR;
static const char *PREFERRED_LANGUAGES;
static const char *APP_LANGUAGE_KEY;
static const char *I18N_PREFERENCES_FILE_NAME;
static constexpr int CONFIG_LEN = 128;
static constexpr uint32_t LANGUAGE_LEN = 2;
};