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", "init",
"ipc", "ipc",
"napi", "napi",
"preferences",
"resource_management", "resource_management",
"samgr" "samgr"
], ],

View File

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

View File

@ -14,6 +14,7 @@
*/ */
#ifdef SUPPORT_APP_PREFERRED_LANGUAGE #ifdef SUPPORT_APP_PREFERRED_LANGUAGE
#include <regex> #include <regex>
#include "application_context.h"
#include "bundle_info.h" #include "bundle_info.h"
#include "bundle_mgr_interface.h" #include "bundle_mgr_interface.h"
#include "hap_resource.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_TAILOR = "/assets/entry/resources.index";
const char *PreferredLanguage::RESOURCE_PATH_SPLITOR = "/"; const char *PreferredLanguage::RESOURCE_PATH_SPLITOR = "/";
const char *PreferredLanguage::PREFERRED_LANGUAGES = "persist.sys.preferredLanguages"; 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, bool PreferredLanguage::AddPreferredLanguageExist(std::vector<std::string> &preferredLanguageList, int languageIdx,
int index, const std::string& language) int index, const std::string& language)
@ -200,108 +203,57 @@ std::string PreferredLanguage::GetFirstPreferredLanguage()
} }
#ifdef SUPPORT_APP_PREFERRED_LANGUAGE #ifdef SUPPORT_APP_PREFERRED_LANGUAGE
std::string PreferredLanguage::GetBundleName() std::shared_ptr<NativePreferences::Preferences> PreferredLanguage::GetI18nAppPreferences()
{ {
auto systemAbilityManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); std::shared_ptr<AbilityRuntime::ApplicationContext> appContext = AbilityRuntime::ApplicationContext::GetInstance();
if (systemAbilityManager == nullptr) { std::string preferencesDirPath = appContext->GetPreferencesDir();
HiLog::Error(LABEL, "Failed to create system ability manager."); std::string i18nPreferencesFilePath = preferencesDirPath + I18N_PREFERENCES_FILE_NAME;
return ""; 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); return preferences;
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;
} }
std::string PreferredLanguage::GetAppPreferredLanguage() std::string PreferredLanguage::GetAppPreferredLanguage()
{ {
std::vector<std::string> preferredLanguageList = GetPreferredLanguageList(); std::shared_ptr<NativePreferences::Preferences> preferences = GetI18nAppPreferences();
std::set<std::string> resources = GetResources(); if (preferences == nullptr) {
int minmumMatchedIdx = -1; HiLog::Error(LABEL,
for (size_t i = 0; i < preferredLanguageList.size(); i++) { "PreferredLanguage::GetAppPreferredLanguage get i18n preferences failed, return system language.");
for (std::set<std::string>::iterator it = resources.begin(); it != resources.end(); ++it) { return LocaleConfig::GetSystemLanguage();
std::string preferredLanguage = preferredLanguageList[i];
if (preferredLanguage == "en-Qaag") {
preferredLanguage = "en-Latn";
} }
if (IsMatched(preferredLanguage, *it)) { std::string res = preferences->GetString(PreferredLanguage::APP_LANGUAGE_KEY, "");
minmumMatchedIdx = (int)i; if (res.length() == 0) {
break; HiLog::Info(LABEL,
"PreferredLanguage::GetAppPreferredLanguage app language is empty, return system language.");
return LocaleConfig::GetSystemLanguage();
} }
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;
} }
if (minmumMatchedIdx != -1) { int32_t status = preferences->PutString(PreferredLanguage::APP_LANGUAGE_KEY, language);
return preferredLanguageList[minmumMatchedIdx]; if (status != 0) {
errCode = I18nErrorCode::FAILED;
HiLog::Error(LABEL,
"PreferredLanguage::SetAppPreferredLanguage set app language to i18n preferences failed.");
return;
} }
return preferredLanguageList[0]; preferences->Flush();
} }
#endif #endif

View File

@ -11,6 +11,7 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import("//base/global/i18n/i18n.gni")
import("//build/ohos.gni") import("//build/ohos.gni")
group("build_module") { group("build_module") {
@ -92,6 +93,9 @@ ohos_shared_library("i18n") {
"hilog:libhilog", "hilog:libhilog",
"napi:ace_napi", "napi:ace_napi",
] ]
if (i18n_support_app_preferred_language) {
defines = [ "SUPPORT_APP_PREFERRED_LANGUAGE" ]
}
relative_install_dir = "module" relative_install_dir = "module"
subsystem_name = "global" subsystem_name = "global"
part_name = "i18n" 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); ErrorUtil::NapiThrow(env, I18N_NOT_VALID, true);
return nullptr; 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; return nullptr;
} }

View File

@ -19,6 +19,9 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "i18n_types.h" #include "i18n_types.h"
#ifdef SUPPORT_APP_PREFERRED_LANGUAGE
#include "preferences_helper.h"
#endif
namespace OHOS { namespace OHOS {
namespace Global { namespace Global {
@ -30,7 +33,23 @@ public:
static std::vector<std::string> GetPreferredLanguageList(); static std::vector<std::string> GetPreferredLanguageList();
static std::string GetFirstPreferredLanguage(); static std::string GetFirstPreferredLanguage();
#ifdef SUPPORT_APP_PREFERRED_LANGUAGE #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(); 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 #endif
static std::string GetPreferredLocale(); static std::string GetPreferredLocale();
@ -43,14 +62,14 @@ private:
static bool IsValidTag(const std::string &tag); static bool IsValidTag(const std::string &tag);
static void Split(const std::string &src, const std::string &sep, std::vector<std::string> &dest); static void Split(const std::string &src, const std::string &sep, std::vector<std::string> &dest);
#ifdef SUPPORT_APP_PREFERRED_LANGUAGE #ifdef SUPPORT_APP_PREFERRED_LANGUAGE
static std::string GetBundleName(); static std::shared_ptr<NativePreferences::Preferences> GetI18nAppPreferences();
static std::set<std::string> GetResources();
static bool IsMatched(const std::string& preferred, const std::string& resource);
#endif #endif
static const char *RESOURCE_PATH_HEAD; static const char *RESOURCE_PATH_HEAD;
static const char *RESOURCE_PATH_TAILOR; static const char *RESOURCE_PATH_TAILOR;
static const char *RESOURCE_PATH_SPLITOR; static const char *RESOURCE_PATH_SPLITOR;
static const char *PREFERRED_LANGUAGES; 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 int CONFIG_LEN = 128;
static constexpr uint32_t LANGUAGE_LEN = 2; static constexpr uint32_t LANGUAGE_LEN = 2;
}; };