diff --git a/bundle.json b/bundle.json index db0e04259742916fe499c4b6d7082e2464d0ab64..9f17e004b70ae041c1079fcd2adbeaab65a2a61c 100644 --- a/bundle.json +++ b/bundle.json @@ -58,6 +58,7 @@ "napi", "hilog", "relational_store", + "data_share", "device_usage_statistics", "bundle_framework", "time_service", @@ -79,10 +80,11 @@ "kv_store", "ffrt", "device_standby", - "data_share" + "resource_management" ], "third_party": [ - "libuv" + "libuv", + "icu" ] }, "build": { diff --git a/frameworks/ans/src/reminder_request.cpp b/frameworks/ans/src/reminder_request.cpp index d5f1af06dfaa6bb892760f9274b9a5cd038c820e..15d192aed8de1eb1142400354a507bd008a0cbd0 100644 --- a/frameworks/ans/src/reminder_request.cpp +++ b/frameworks/ans/src/reminder_request.cpp @@ -190,7 +190,7 @@ std::string ReminderRequest::Dump() const } ReminderRequest& ReminderRequest::SetActionButton(const std::string &title, const ActionButtonType &type, - const std::shared_ptr &buttonWantAgent, + const std::string &resource, const std::shared_ptr &buttonWantAgent, const std::shared_ptr &buttonDataShareUpdate) { if ((type != ActionButtonType::CLOSE) && (type != ActionButtonType::SNOOZE) && (type != ActionButtonType::CUSTOM)) { @@ -200,6 +200,7 @@ ReminderRequest& ReminderRequest::SetActionButton(const std::string &title, cons ActionButtonInfo actionButtonInfo; actionButtonInfo.type = type; actionButtonInfo.title = title; + actionButtonInfo.resource = resource; actionButtonInfo.wantAgent = buttonWantAgent; actionButtonInfo.dataShareUpdate = buttonDataShareUpdate; @@ -245,6 +246,11 @@ void ReminderRequest::InitUid(const int32_t &uid) uid_ = uid; } +void ReminderRequest::InitBundleName(const std::string &bundleName) +{ + bundleName_ = bundleName; +} + bool ReminderRequest::IsExpired() const { return isExpired_; @@ -611,6 +617,7 @@ void ReminderRequest::RecoverActionButton(const std::shared_ptr(); std::string title = root.at("title").get(); + std::string resource = root.at("resource").get(); auto buttonWantAgent = std::make_shared(); if (!root["wantAgent"].empty()) { nlohmann::json wantAgent = root["wantAgent"]; @@ -625,7 +632,7 @@ void ReminderRequest::RecoverActionButton(const std::shared_ptrvaluesBucket = dataShareUpdate.at("valuesBucket").get(); } SetActionButton(title, ActionButtonType(std::stoi(type, nullptr)), - buttonWantAgent, buttonDataShareUpdate); + resource, buttonWantAgent, buttonDataShareUpdate); continue; } // old method Soon to be deleted @@ -638,10 +645,11 @@ void ReminderRequest::RecoverActionButton(const std::shared_ptrpkgName = singleButton.at(BUTTON_PKG_INDEX); buttonWantAgent->abilityName = singleButton.at(BUTTON_ABILITY_INDEX); } + std::string resource = ""; auto buttonDataShareUpdate = std::make_shared(); SetActionButton(singleButton.at(BUTTON_TITLE_INDEX), ActionButtonType(std::stoi(singleButton.at(BUTTON_TYPE_INDEX), nullptr)), - buttonWantAgent, buttonDataShareUpdate); + resource, buttonWantAgent, buttonDataShareUpdate); ANSR_LOGI("RecoverButton title:%{public}s, pkgName:%{public}s, abilityName:%{public}s", singleButton.at(BUTTON_TITLE_INDEX).c_str(), buttonWantAgent->pkgName.c_str(), buttonWantAgent->abilityName.c_str()); @@ -900,6 +908,11 @@ int32_t ReminderRequest::GetUid() const return uid_; } +std::string ReminderRequest::GetBundleName() const +{ + return bundleName_; +} + void ReminderRequest::SetSystemApp(bool isSystem) { isSystemApp_ = isSystem; @@ -1128,6 +1141,10 @@ bool ReminderRequest::Marshalling(Parcel &parcel) const ANSR_LOGE("Failed to write action button title"); return false; } + if (!parcel.WriteString(static_cast(button.second.resource))) { + ANSR_LOGE("Failed to write action button resource"); + return false; + } if (button.second.wantAgent == nullptr) { ANSR_LOGE("button wantAgent is null"); return false; @@ -1308,6 +1325,7 @@ bool ReminderRequest::ReadFromParcel(Parcel &parcel) } ActionButtonType type = static_cast(buttonType); std::string title = parcel.ReadString(); + std::string resource = parcel.ReadString(); std::string pkgName = parcel.ReadString(); std::string abilityName = parcel.ReadString(); std::string uri = parcel.ReadString(); @@ -1316,6 +1334,7 @@ bool ReminderRequest::ReadFromParcel(Parcel &parcel) ActionButtonInfo info; info.type = type; info.title = title; + info.resource = resource; info.wantAgent = std::make_shared(); info.wantAgent->pkgName = pkgName; info.wantAgent->abilityName = abilityName; @@ -1385,6 +1404,7 @@ std::string ReminderRequest::GetButtonInfo() const nlohmann::json root; root["type"] = std::to_string(static_cast(button.first)); root["title"] = buttonInfo.title; + root["resource"] = buttonInfo.resource; if (buttonInfo.wantAgent != nullptr) { nlohmann::json wantAgentfriends; wantAgentfriends["pkgName"] = buttonInfo.wantAgent->pkgName; @@ -1910,5 +1930,23 @@ void ReminderRequest::AddColumn( sqlOfAddColumns += name + " " + type; } } + +void ReminderRequest::OnLanguageChange(const std::shared_ptr &resMgr) +{ + if (resMgr == nullptr) { + return; + } + // update title + for (auto &button : actionButtonMap_) { + std::string title; + resMgr->GetStringByName(button.second.resource.c_str(), title); + if (title.empty()) { + continue; + } + button.second.title = title; + } + // update action button + UpdateActionButtons(false); +} } } \ No newline at end of file diff --git a/frameworks/ans/test/unittest/BUILD.gn b/frameworks/ans/test/unittest/BUILD.gn index 80f902f98e0c8e1fcdc57b34cc1bc5b6fe17c732..3011f8586071760de1e0f7cb7f42ee0c356deaaf 100644 --- a/frameworks/ans/test/unittest/BUILD.gn +++ b/frameworks/ans/test/unittest/BUILD.gn @@ -95,9 +95,11 @@ ohos_unittest("reminder_request_test") { "include", "/${services_path}/ans/include", "${services_path}/ans/test/unittest/mock/include", + "${frameworks_module_ans_path}/test/unittest/mock/include", ] sources = [ + "${frameworks_module_ans_path}/test/unittest/mock/mock_resource_manager.cpp", "${frameworks_module_ans_path}/test/unittest/reminder_request_branch_test/mock_reminder_request.cpp", "${frameworks_module_ans_path}/test/unittest/reminder_request_test.cpp", ] diff --git a/frameworks/ans/test/unittest/mock/include/mock_resource_manager_impl.h b/frameworks/ans/test/unittest/mock/include/mock_resource_manager_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..add8c722644e6dd170c9e7b98dd3abb823c41d54 --- /dev/null +++ b/frameworks/ans/test/unittest/mock/include/mock_resource_manager_impl.h @@ -0,0 +1,530 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_MOCK_RESOURCE_MANAGER_IMPL_H +#define OHOS_MOCK_RESOURCE_MANAGER_IMPL_H + +#include +#include +#include +#include "resource_manager.h" + +namespace OHOS { +namespace Global { +namespace Resource { +class ResourceManagerImpl : public ResourceManager { +public: + ResourceManagerImpl(); + ~ResourceManagerImpl(); + +public: + void Init(); + + /** + * Add resource path to hap paths + * @param path the resource path + * @return true if add resource path success, else false + */ + virtual bool AddResource(const char *path); + + /** + * Add resource path to overlay paths + * @param path the resource path + * @param overlayPaths the exist overlay resource path + * @return true if add resource path success, else false + */ + virtual bool AddResource(const std::string &path, const std::vector &overlayPaths); + + /** + * Remove resource path to overlay paths + * @param path the resource path + * @param overlayPaths the exist overlay resource path + * @return true if add resource path success, else false + */ + virtual bool RemoveResource(const std::string &path, const std::vector &overlayPaths); + + /** + * Update the resConfig + * @param resConfig the resource config + * @return SUCCESS if the resConfig updated success, else HAP_INIT_FAILED + */ + virtual RState UpdateResConfig(ResConfig &resConfig); + + /** + * Get the resConfig + * @param resConfig the resource config + */ + virtual void GetResConfig(ResConfig &resConfig); + + /** + * Get string resource by Id + * @param id the resource Id + * @param outValue the string resource write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetStringById(uint32_t id, std::string &outValue); + + /** + * Get string by resource name + * @param name the resource name + * @param outValue the resource write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetStringByName(const char *name, std::string &outValue); + + /** + * Get string format by resource id + * @param id the resource id + * @param outValue the resource write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetStringFormatById(std::string &outValue, uint32_t id, ...); + + /** + * Get string format by resource name + * @param name the resource name + * @param outValue the resource write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetStringFormatByName(std::string &outValue, const char *name, ...); + + /** + * Get the STRINGARRAY resource by resource id + * @param id the resource id + * @param outValue the resource write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetStringArrayById(uint32_t id, std::vector &outValue); + + /** + * Get the STRINGARRAY resource by resource name + * @param name the resource name + * @param outValue the resource write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetStringArrayByName(const char *name, std::vector &outValue); + + /** + * Get the PATTERN resource by resource id + * @param id the resource id + * @param outValue the resource write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetPatternById(uint32_t id, std::map &outValue); + + /** + * Get the PATTERN resource by resource name + * @param name the resource name + * @param outValue the resource write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetPatternByName(const char *name, std::map &outValue); + + /** + * Get the plural string by resource id + * @param id the resource id + * @param quantity the language quantity + * @param outValue the resource write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetPluralStringById(uint32_t id, int quantity, std::string &outValue); + + /** + * Get the plural string by resource name + * @param name the resource name + * @param quantity the language quantity + * @param outValue the resource write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetPluralStringByName(const char *name, int quantity, std::string &outValue); + + /** + * Get the plural format string by resource id + * @param outValue the resource write to + * @param id the resource id + * @param quantity the language quantity + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetPluralStringByIdFormat(std::string &outValue, uint32_t id, int quantity, ...); + + /** + * Get the plural format string by resource name + * @param outValue the resource write to + * @param id the resource id + * @param quantity the language quantity + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetPluralStringByNameFormat(std::string &outValue, const char *name, int quantity, ...); + + /** + * Get the THEME resource by resource id + * @param id the resource id + * @param outValue the resource write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetThemeById(uint32_t id, std::map &outValue); + + /** + * Get the THEME resource by resource name + * @param name the resource name + * @param outValue the resource write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetThemeByName(const char *name, std::map &outValue); + + /** + * Get the BOOLEAN resource by resource id + * @param id the resource id + * @param outValue the obtain boolean value write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetBooleanById(uint32_t id, bool &outValue); + + /** + * Get the BOOLEAN resource by resource name + * @param name the resource name + * @param outValue the obtain boolean value write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetBooleanByName(const char *name, bool &outValue); + + /** + * Get the INTEGER resource by resource id + * @param id the resource id + * @param outValue the obtain Integer value write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetIntegerById(uint32_t id, int &outValue); + + /** + * Get the INTEGER resource by resource name + * @param name the resource name + * @param outValue the obtain Integer value write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetIntegerByName(const char *name, int &outValue); + + /** + * Get the FLOAT resource by resource id + * @param id the resource id + * @param outValue the obtain float value write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetFloatById(uint32_t id, float &outValue); + + /** + * Get the FLOAT resource by resource id + * @param id the resource id + * @param outValue the obtain float value write to + * @param unit the unit do not in parsing + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetFloatById(uint32_t id, float &outValue, std::string &unit); + + /** + * Get the FLOAT resource by resource name + * @param name the resource name + * @param outValue the obtain float value write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetFloatByName(const char *name, float &outValue); + + /** + * Get the FLOAT resource by resource id + * @param id the resource id + * @param outValue the obtain float value write to + * @param unit the string do not in parsing + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetFloatByName(const char *name, float &outValue, std::string &unit); + + /** + * Get the INTARRAY resource by resource id + * @param id the resource id + * @param outValue the obtain resource value convert to vector write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetIntArrayById(uint32_t id, std::vector &outValue); + + /** + * Get the INTARRAY resource by resource name + * @param name the resource name + * @param outValue the obtain resource value convert to vector write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetIntArrayByName(const char *name, std::vector &outValue); + + /** + * Get the COLOR resource by resource id + * @param id the resource id + * @param outValue the obtain resource value convert to uint32_t write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetColorById(uint32_t id, uint32_t &outValue); + + /** + * Get the COLOR resource by resource name + * @param name the resource name + * @param outValue the obtain resource value convert to uint32_t write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetColorByName(const char *name, uint32_t &outValue); + + /** + * Get the PROF resource by resource id + * @param id the resource id + * @param outValue the obtain resource path write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetProfileById(uint32_t id, std::string &outValue); + + /** + * Get the PROF resource by resource name + * @param name the resource name + * @param outValue the obtain resource path write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetProfileByName(const char *name, std::string &outValue); + + /** + * Get the MEDIA resource by resource id + * @param id the resource id + * @param outValue the obtain resource path write to + * @param density the screen density, within the area of OHOS::Global::Resource::ScreenDensity + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetMediaById(uint32_t id, std::string &outValue, uint32_t density = 0); + + /** + * Get the MEDIA resource by resource name + * @param name the resource name + * @param outValue the obtain resource path write to + * @param density the screen density, within the area of OHOS::Global::Resource::ScreenDensity + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetMediaByName(const char *name, std::string &outValue, uint32_t density = 0); + + /** + * Get the raw file path by resource name + * @param name the resource name + * @param outValue the obtain resource path write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetRawFilePathByName(const std::string &name, std::string &outValue); + + /** + * Get the rawFile descriptor by resource name + * @param name the resource name + * @param descriptor the obtain raw file member fd, length, offet write to + * @return SUCCESS if resource exist, else ERROR + */ + virtual RState GetRawFileDescriptor(const std::string &name, RawFileDescriptor &descriptor); + + /** + * Close rawFile descriptor by resource name + * @param name the resource name + * @return SUCCESS if close the rawFile descriptor, else ERROR + */ + virtual RState CloseRawFileDescriptor(const std::string &name); + + /** + * Get all resource paths + * @return The vector of resource paths + */ + std::vector GetResourcePaths(); + + /** + * Get the MEDIA data by resource id + * @param id the resource id + * @param len the data len write to + * @param outValue the obtain resource path write to + * @param density the screen density, within the area of OHOS::Global::Resource::ScreenDensity + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetMediaDataById(uint32_t id, size_t &len, std::unique_ptr &outValue, + uint32_t density = 0); + + /** + * Get the MEDIA data by resource name + * @param name the resource name + * @param len the data len write to + * @param outValue the obtain resource path write to + * @param density the screen density, within the area of OHOS::Global::Resource::ScreenDensity + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetMediaDataByName(const char *name, size_t &len, std::unique_ptr &outValue, + uint32_t density = 0); + + /** + * Get the MEDIA base64 data resource by resource id + * @param id the resource id + * @param outValue the media base64 data + * @param density the screen density, within the area of OHOS::Global::Resource::ScreenDensity + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetMediaBase64DataById(uint32_t id, std::string &outValue, uint32_t density = 0); + + /** + * Get the MEDIA base64 data resource by resource id + * @param name the resource name + * @param outValue the media base64 data + * @param density the screen density, within the area of OHOS::Global::Resource::ScreenDensity + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetMediaBase64DataByName(const char *name, std::string &outValue, uint32_t density = 0); + + /** + * Get the PROF resource by resource id + * @param name the resource id + * @param len the data len write to + * @param outValue the obtain resource path write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetProfileDataById(uint32_t id, size_t &len, std::unique_ptr &outValue); + + /** + * Get the PROF resource by resource name + * @param name the resource name + * @param len the data len write to + * @param outValue the obtain resource path write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetProfileDataByName(const char *name, size_t &len, std::unique_ptr &outValue); + + /** + * Get the rawFile base64 from hap by rawFile name + * @param rawFileName the rawFile name + * @param len the data len write to + * @param outValue the obtain resource path write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetRawFileFromHap(const std::string &rawFileName, size_t &len, + std::unique_ptr &outValue); + + /** + * Get the rawFile Descriptor from hap by rawFile name + * @param rawFileName the rawFile name + * @param descriptor the raw file member fd, length, offet write to + * @return SUCCESS if resource exist, else NOT_FOUND + */ + virtual RState GetRawFileDescriptorFromHap(const std::string &rawFileName, RawFileDescriptor &descriptor); + + /** + * Is load hap + * @param hapPath the hap path + */ + virtual RState IsLoadHap(std::string &hapPath); + + /** + * Get the raw file list + * @param rawDirPath the rawfile directory path + * @param rawfileList the rawfile list write to + * @return SUCCESS if resource exist, else not found + */ + virtual RState GetRawFileList(const std::string &rawDirPath, std::vector& rawfileList); + + /** + * Get the drawable information for given resId, mainly about type, len, buffer + * @param id the resource id + * @param type the drawable type + * @param len the drawable buffer length + * @param outValue the drawable buffer write to + * @param density the drawable density + * @return SUCCESS if resource exist, else not found + */ + virtual RState GetDrawableInfoById(uint32_t id, std::string &type, size_t &len, + std::unique_ptr &outValue, uint32_t density = 0); + + /** + * Get the drawable information for given resName, mainly about type, len, buffer + * @param name the resource Name + * @param type the drawable type + * @param len the drawable buffer length + * @param outValue the drawable buffer write to + * @param density the drawable density + * @return SUCCESS if resource exist, else not found + */ + virtual RState GetDrawableInfoByName(const char *name, std::string &type, size_t &len, + std::unique_ptr &outValue, uint32_t density = 0); + + /** + * Get string format by resource id + * @param id the resource id + * @param outValue the resource write to + * @param jsParams the formatting string resource js parameters, the tuple first parameter represents the type, + * napi_number is denoted by NAPI_NUMBER, napi_string is denoted by NAPI_STRING, + * the tuple second parameter represents the value + * @return SUCCESS if resource exists and was formatted successfully, else ERROR + */ + virtual RState GetStringFormatById(uint32_t id, std::string &outValue, + std::vector> &jsParams); + + /** + * Get string format by resource name + * @param name the resource name + * @param outValue the resource write to + * @param jsParams the formatting string resource js parameters, the tuple first parameter represents the type, + * napi_number is denoted by NAPI_NUMBER, napi_string is denoted by NAPI_STRING, + * the tuple second parameter represents the value + * @return SUCCESS if resource exists and was formatted successfully, else ERROR + */ + virtual RState GetStringFormatByName(const char *name, std::string &outValue, + std::vector> &jsParams); + + /** + * Get the resource limit keys value which every binary bit corresponds to existing limit key {@link KeyType} + * + * @return the resource limit keys + */ + virtual uint32_t GetResourceLimitKeys(); + + /** + * Add the overlay resource for current application + * @param path the overlay resource path + * @return true if add resource path success, else false + */ + virtual bool AddAppOverlay(const std::string &path); + + /** + * Remove the overlay resource for current application + * @param path the overlay resource path + * @return true if add resource path success, else false + */ + virtual bool RemoveAppOverlay(const std::string &path); + + /** + * Get the rawFile descriptor from resource name + * + * @param name the resource name + * @param descriptor the obtain raw file member fd, length, offet write to + * @return SUCCESS if resource exist, else ERROR + */ + virtual RState GetRawFdNdkFromHap(const std::string &name, RawFileDescriptor &descriptor); + + /** + * Get the resource id by resType and resName + * + * @param resTypeName the resType and resName + * @param resId the resId write to + * @return SUCCESS if resource exist, else ERROR + */ + virtual RState GetResId(const std::string &resTypeName, uint32_t &resId); + +private: + std::map resources_; +}; +} // namespace Resource +} // namespace Global +} // namespace OHOS +#endif \ No newline at end of file diff --git a/frameworks/ans/test/unittest/mock/mock_resource_manager.cpp b/frameworks/ans/test/unittest/mock/mock_resource_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fc7ed534cb971324ddbc3bcb845d7ba053d74e2e --- /dev/null +++ b/frameworks/ans/test/unittest/mock/mock_resource_manager.cpp @@ -0,0 +1,339 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mock_resource_manager_impl.h" + +namespace OHOS { +namespace Global { +namespace Resource { +ResourceManager *CreateResourceManager() +{ + ResourceManagerImpl *impl = new (std::nothrow) ResourceManagerImpl; + return impl; +} + +ResourceManager::~ResourceManager() {} + +ResourceManagerImpl::ResourceManagerImpl() {} + +ResourceManagerImpl::~ResourceManagerImpl() {} + +void ResourceManagerImpl::Init() +{ + resources_.emplace("snooze", "SNOOZE_TEST"); + resources_.emplace("close", "CLOSE_TEST"); +} + +bool ResourceManagerImpl::AddResource(const char *path) +{ + return true; +} + +bool ResourceManagerImpl::AddResource(const std::string &path, const std::vector &overlayPaths) +{ + return true; +} + +bool ResourceManagerImpl::RemoveResource(const std::string &path, const std::vector &overlayPaths) +{ + return true; +} + +RState ResourceManagerImpl::UpdateResConfig(ResConfig &resConfig) +{ + return SUCCESS; +} + +void ResourceManagerImpl::GetResConfig(ResConfig &resConfig) {} + +RState ResourceManagerImpl::GetStringById(uint32_t id, std::string &outValue) +{ + outValue = "ENTRY"; + return SUCCESS; +} + +RState ResourceManagerImpl::GetStringByName(const char *name, std::string &outValue) +{ + if (name == nullptr) { + return NOT_FOUND; + } + std::string key(name); + auto iter = resources_.find(key); + if (iter == resources_.end()) { + return NOT_FOUND; + } + outValue = iter->second; + return SUCCESS; +} + +RState ResourceManagerImpl::GetStringFormatById(std::string &outValue, uint32_t id, ...) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetStringFormatByName(std::string &outValue, const char *name, ...) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetStringArrayById(uint32_t id, std::vector &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetStringArrayByName(const char *name, std::vector &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetPatternById(uint32_t id, std::map &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetPatternByName(const char *name, std::map &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetPluralStringById(uint32_t id, int32_t quantity, std::string &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetPluralStringByName(const char *name, int32_t quantity, std::string &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetPluralStringByIdFormat(std::string &outValue, uint32_t id, int32_t quantity, ...) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetPluralStringByNameFormat(std::string &outValue, const char *name, int32_t quantity, ...) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetThemeById(uint32_t id, std::map &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetThemeByName(const char *name, std::map &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetBooleanById(uint32_t id, bool &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetBooleanByName(const char *name, bool &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetIntegerById(uint32_t id, int32_t &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetIntegerByName(const char *name, int32_t &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetFloatById(uint32_t id, float &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetFloatById(uint32_t id, float &outValue, std::string &unit) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetFloatByName(const char *name, float &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetFloatByName(const char *name, float &outValue, std::string &unit) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetIntArrayById(uint32_t id, std::vector &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetIntArrayByName(const char *name, std::vector &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetColorById(uint32_t id, uint32_t &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetColorByName(const char *name, uint32_t &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetProfileById(uint32_t id, std::string &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetProfileByName(const char *name, std::string &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetMediaById(uint32_t id, std::string &outValue, uint32_t density) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetMediaByName(const char *name, std::string &outValue, uint32_t density) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetRawFilePathByName(const std::string &name, std::string &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetRawFileDescriptor(const std::string &name, RawFileDescriptor &descriptor) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::CloseRawFileDescriptor(const std::string &name) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetMediaDataById(uint32_t id, size_t &len, std::unique_ptr &outValue, + uint32_t density) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetMediaDataByName(const char *name, size_t &len, std::unique_ptr &outValue, + uint32_t density) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetMediaBase64DataById(uint32_t id, std::string &outValue, uint32_t density) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetMediaBase64DataByName(const char *name, std::string &outValue, uint32_t density) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetProfileDataById(uint32_t id, size_t &len, std::unique_ptr &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetProfileDataByName(const char *name, size_t &len, std::unique_ptr &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetRawFileFromHap(const std::string &rawFileName, size_t &len, + std::unique_ptr &outValue) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetRawFileDescriptorFromHap(const std::string &rawFileName, RawFileDescriptor &descriptor) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::IsLoadHap(std::string &hapPath) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetRawFileList(const std::string &rawDirPath, std::vector& rawfileList) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetDrawableInfoById(uint32_t id, std::string &type, size_t &len, + std::unique_ptr &outValue, uint32_t density) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetDrawableInfoByName(const char *name, std::string &type, size_t &len, + std::unique_ptr &outValue, uint32_t density) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetStringFormatById(uint32_t id, std::string &outValue, + std::vector> &jsParams) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetStringFormatByName(const char *name, std::string &outValue, + std::vector> &jsParams) +{ + return SUCCESS; +} + +uint32_t ResourceManagerImpl::GetResourceLimitKeys() +{ + return 0; +} + +bool ResourceManagerImpl::AddAppOverlay(const std::string &path) +{ + return true; +} + +bool ResourceManagerImpl::RemoveAppOverlay(const std::string &path) +{ + return true; +} + +RState ResourceManagerImpl::GetRawFdNdkFromHap(const std::string &name, ResourceManager::RawFileDescriptor &descriptor) +{ + return SUCCESS; +} + +RState ResourceManagerImpl::GetResId(const std::string &resTypeName, uint32_t &resId) +{ + return SUCCESS; +} +} // namespace Resource +} // namespace Global +} // namespace OHOS \ No newline at end of file diff --git a/frameworks/ans/test/unittest/reminder_request_test.cpp b/frameworks/ans/test/unittest/reminder_request_test.cpp index 19d2f424cb17bffae81f42621f37ed433dd733cc..04d39f2bc0b995c2f80815c3db894c2079744f51 100644 --- a/frameworks/ans/test/unittest/reminder_request_test.cpp +++ b/frameworks/ans/test/unittest/reminder_request_test.cpp @@ -18,6 +18,7 @@ #define private public #define protected public #include "reminder_request.h" +#include "mock_resource_manager_impl.h" #undef private #undef protected @@ -1047,9 +1048,10 @@ HWTEST_F(ReminderRequestTest, SetActionButton_00001, Function | SmallTest | Leve std::shared_ptr reminderRequestChild = std::make_shared(); ASSERT_NE(nullptr, reminderRequestChild); std::string title = "this is title"; + std::string resource = "invalid"; Notification::ReminderRequest::ActionButtonType type = Notification::ReminderRequest::ActionButtonType::INVALID; - reminderRequestChild->SetActionButton(title, type); + reminderRequestChild->SetActionButton(title, type, resource); } /** @@ -1063,9 +1065,10 @@ HWTEST_F(ReminderRequestTest, SetActionButton_00002, Function | SmallTest | Leve std::shared_ptr reminderRequestChild = std::make_shared(); ASSERT_NE(nullptr, reminderRequestChild); std::string title = "this is title"; + std::string resource = "close"; Notification::ReminderRequest::ActionButtonType type2 = Notification::ReminderRequest::ActionButtonType::CLOSE; - reminderRequestChild->SetActionButton(title, type2); + reminderRequestChild->SetActionButton(title, type2, resource); } /** @@ -1079,9 +1082,10 @@ HWTEST_F(ReminderRequestTest, SetActionButton_00003, Function | SmallTest | Leve std::shared_ptr reminderRequestChild = std::make_shared(); ASSERT_NE(nullptr, reminderRequestChild); std::string title = "this is title"; + std::string resource = "snooze"; Notification::ReminderRequest::ActionButtonType type3 = Notification::ReminderRequest::ActionButtonType::SNOOZE; - reminderRequestChild->SetActionButton(title, type3); + reminderRequestChild->SetActionButton(title, type3, resource); } /** @@ -1095,13 +1099,14 @@ HWTEST_F(ReminderRequestTest, SetActionButton_00004, Function | SmallTest | Leve std::shared_ptr reminderRequestChild = std::make_shared(); ASSERT_NE(nullptr, reminderRequestChild); std::string title = "this is title"; + std::string resource = "CLOSE"; Notification::ReminderRequest::ActionButtonType type2 = Notification::ReminderRequest::ActionButtonType::CLOSE; std::shared_ptr buttonWantAgent = std::make_shared(); std::shared_ptr buttonDataShareUpdate = std::make_shared(); - reminderRequestChild->SetActionButton(title, type2, buttonWantAgent, buttonDataShareUpdate); + reminderRequestChild->SetActionButton(title, type2, resource, buttonWantAgent, buttonDataShareUpdate); } /** @@ -1115,13 +1120,14 @@ HWTEST_F(ReminderRequestTest, SetActionButton_00005, Function | SmallTest | Leve std::shared_ptr reminderRequestChild = std::make_shared(); ASSERT_NE(nullptr, reminderRequestChild); std::string title = "this is title"; + std::string resource = "SNOOZE"; Notification::ReminderRequest::ActionButtonType type3 = Notification::ReminderRequest::ActionButtonType::SNOOZE; std::shared_ptr buttonWantAgent = std::make_shared(); std::shared_ptr buttonDataShareUpdate = std::make_shared(); - reminderRequestChild->SetActionButton(title, type3, buttonWantAgent, buttonDataShareUpdate); + reminderRequestChild->SetActionButton(title, type3, resource, buttonWantAgent, buttonDataShareUpdate); } /** @@ -1793,5 +1799,71 @@ HWTEST_F(ReminderRequestTest, SetCustomButtonUri_00001, Function | SmallTest | L std::string ret = "test"; EXPECT_EQ(result, ret); } + +/** + * @tc.name: InitBundleName_00001 + * @tc.desc: Test InitBundleName with normal parameters. + * @tc.type: FUNC + * @tc.require: issueI89858 + */ +HWTEST_F(ReminderRequestTest, InitBundleName_00001, Function | SmallTest | Level1) +{ + auto rrc = std::make_shared(); + std::string bundleName = "com.example.myapplication"; + rrc->InitBundleName(bundleName); + EXPECT_EQ(rrc->GetBundleName(), bundleName); +} + +/** + * @tc.name: InitBundleName_00002 + * @tc.desc: Test InitBundleName with special parameters. + * @tc.type: FUNC + * @tc.require: issueI89858 + */ +HWTEST_F(ReminderRequestTest, InitBundleName_00002, Function | SmallTest | Level1) +{ + auto rrc = std::make_shared(); + std::string bundleName = "com.example.myapplication.~!@#$%^&*()"; + rrc->InitBundleName(bundleName); + EXPECT_EQ(rrc->GetBundleName(), bundleName); +} + +/** + * @tc.name: OnLanguageChange_00001 + * @tc.desc: Test OnLanguageChange. + * @tc.type: FUNC + * @tc.require: issueI89858 + */ +HWTEST_F(ReminderRequestTest, OnLanguageChange_00001, Function | SmallTest | Level1) +{ + // Given + auto rrc = std::make_shared(); + // add button snooze + std::string title = "this is title snooze"; + std::string resource = "snooze"; + Notification::ReminderRequest::ActionButtonType type = + Notification::ReminderRequest::ActionButtonType::SNOOZE; + rrc->SetActionButton(title, type, resource); + // add button close + title = "this is title close"; + resource = "close"; + type = Notification::ReminderRequest::ActionButtonType::CLOSE; + rrc->SetActionButton(title, type, resource); + + // When + auto resMgr = std::make_shared(); + resMgr->Init(); + rrc->OnLanguageChange(resMgr); + + // Then + auto iter = rrc->actionButtonMap_.find(type); + EXPECT_NE(iter, rrc->actionButtonMap_.end()); + EXPECT_EQ(iter->second.title, "CLOSE_TEST"); + + type = Notification::ReminderRequest::ActionButtonType::SNOOZE; + iter = rrc->actionButtonMap_.find(type); + EXPECT_NE(iter, rrc->actionButtonMap_.end()); + EXPECT_EQ(iter->second.title, "SNOOZE_TEST"); +} } } diff --git a/frameworks/js/napi/include/reminder/reminder_common.h b/frameworks/js/napi/include/reminder/reminder_common.h index 5d0270706ad99b3eafeec0a185f0078194e220e3..509ac456f339d4fa00cc66a629f2235264e1644a 100644 --- a/frameworks/js/napi/include/reminder/reminder_common.h +++ b/frameworks/js/napi/include/reminder/reminder_common.h @@ -30,6 +30,7 @@ namespace { const char* ACTION_BUTTON = "actionButton"; const char* ACTION_BUTTON_TITLE = "title"; const char* ACTION_BUTTON_TYPE = "type"; +const char* ACTION_BUTTON_RESOURCE = "titleResource"; const char* ALARM_HOUR = "hour"; const char* ALARM_DAYS_OF_WEEK = "daysOfWeek"; const char* ALARM_MINUTE = "minute"; diff --git a/frameworks/js/napi/src/reminder/reminder_common.cpp b/frameworks/js/napi/src/reminder/reminder_common.cpp index 755e4ddff32251024e12e7c2d189306f7f5c7fd4..8aabb69c11b03c56ded24cc017492cb1af3732ac 100644 --- a/frameworks/js/napi/src/reminder/reminder_common.cpp +++ b/frameworks/js/napi/src/reminder/reminder_common.cpp @@ -50,6 +50,7 @@ bool ReminderCommon::GenActionButtons( const napi_env &env, const napi_value &value, std::shared_ptr& reminder, bool isSysApp) { char str[NotificationNapi::STR_MAX_SIZE] = {0}; + char res[NotificationNapi::STR_MAX_SIZE] = {0}; napi_valuetype valuetype = napi_undefined; napi_value actionButtons = nullptr; if (!GetObject(env, value, ReminderAgentNapi::ACTION_BUTTON, actionButtons)) { @@ -84,6 +85,13 @@ bool ReminderCommon::GenActionButtons( ANSR_LOGW("Wrong argument type:%{public}s. buttonType not support.", ACTION_BUTTON); return false; } + + std::string resource = ""; + if (GetStringUtf8(env, actionButton, ReminderAgentNapi::ACTION_BUTTON_RESOURCE, res, + NotificationNapi::STR_MAX_SIZE)) { + resource = std::string(res); + } + std::string title(str); auto buttonWantAgent = std::make_shared(); if (ReminderRequest::ActionButtonType(buttonType) == ReminderRequest::ActionButtonType::CUSTOM) { @@ -96,8 +104,9 @@ bool ReminderCommon::GenActionButtons( GetButtonDataShareUpdate(env, actionButton, reminder, buttonDataShareUpdate); } reminder->SetActionButton(title, static_cast(buttonType), - buttonWantAgent, buttonDataShareUpdate); - ANSR_LOGD("button title=%{public}s, type=%{public}d", title.c_str(), buttonType); + resource, buttonWantAgent, buttonDataShareUpdate); + ANSR_LOGD("button title=%{public}s, type=%{public}d, resource=%{public}s", + title.c_str(), buttonType, resource.c_str()); } else { ANSR_LOGW("Parse action button error."); return false; diff --git a/interfaces/inner_api/reminder_request.h b/interfaces/inner_api/reminder_request.h index 3da5a5639e1c711676aa27f399c75ac4c41f3b27..7e8474662e3065a74038def3f4ae629fc30389e3 100644 --- a/interfaces/inner_api/reminder_request.h +++ b/interfaces/inner_api/reminder_request.h @@ -129,6 +129,11 @@ public: */ std::string title = ""; + /** + * resource key(for language) + */ + std::string resource = ""; + /** * The ability that is redirected to when the button is clicked. */ @@ -297,6 +302,13 @@ public: int32_t GetUserId() const; int32_t GetUid() const; + /** + * @brief Obtains bundle name + * + * @return bundle name + */ + std::string GetBundleName() const; + /** * @brief Set the app system. * @@ -344,6 +356,13 @@ public: */ void InitUid(const int32_t &uid); + /** + * @brief Inites reminder bundle name when publish reminder success. + * + * @param bundleName Indicates the bundle name which the reminder belong to + */ + void InitBundleName(const std::string &bundleName); + /** * @brief Check the reminder is alerting or not. * @@ -456,10 +475,11 @@ public: * * @param title Indicates the title of the button. * @param type Indicates the type of the button. + * @param resource Indicates the resource of the button. * @return Current reminder self. */ ReminderRequest& SetActionButton(const std::string &title, const ActionButtonType &type, - const std::shared_ptr &buttonWantAgent = nullptr, + const std::string &resource, const std::shared_ptr &buttonWantAgent = nullptr, const std::shared_ptr &buttonDataShareUpdate = nullptr); /** @@ -643,6 +663,13 @@ public: */ void UpdateNotificationRequest(UpdateNotificationType type, std::string extra); + /** + * @brief When system language change, will call this function. + * need load resource to update button title + * @param resMgr Indicates the resource manager for get button title + */ + void OnLanguageChange(const std::shared_ptr &resMgr); + static int32_t GetActualTime(const TimeTransferType &type, int32_t cTime); static int32_t GetCTime(const TimeTransferType &type, int32_t actualTime); static uint64_t GetDurationSinceEpochInMilli(const time_t target); diff --git a/services/ans/BUILD.gn b/services/ans/BUILD.gn index 9c520123406a6b902803c6867464e28f8e13ad4a..343801d4f59ffe72a404a7645e5101d193076599 100644 --- a/services/ans/BUILD.gn +++ b/services/ans/BUILD.gn @@ -59,6 +59,7 @@ ohos_shared_library("libans") { "src/notification_subscriber_manager.cpp", "src/notification_timer_info.cpp", "src/permission_filter.cpp", + "src/reminder_config_change_observer.cpp", "src/reminder_data_manager.cpp", "src/reminder_event_manager.cpp", "src/reminder_timer_info.cpp", @@ -70,7 +71,10 @@ ohos_shared_library("libans") { defines = [] cflags = [] - deps = [ "${frameworks_module_ans_path}:ans_innerkits" ] + deps = [ + "${frameworks_module_ans_path}:ans_innerkits", + "//third_party/icu/icu4c:shared_icuuc", + ] if (is_double_framework) { cflags += [ "-DCONFIG_DUAL_FRAMEWORK" ] @@ -84,19 +88,24 @@ ohos_shared_library("libans") { external_deps = [ "ability_runtime:ability_manager", + "ability_runtime:app_manager", "ability_runtime:wantagent_innerkits", "access_token:libaccesstoken_sdk", "access_token:libtokenid_sdk", + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", "c_utils:utils", "data_share:datashare_common", "data_share:datashare_consumer", "device_manager:devicemanagersdk", "ffrt:libffrt", "hitrace:hitrace_meter", + "i18n:intl_util", "image_framework:image_native", "kv_store:distributeddata_inner", "os_account:os_account_innerkits", "relational_store:native_rdb", + "resource_management:global_resmgr", "time_service:time_client", ] external_deps += component_external_deps diff --git a/services/ans/include/bundle_manager_helper.h b/services/ans/include/bundle_manager_helper.h index ed3cda547dcd74e725d9a345171173eaa7833302..ea71a8b83916d264a4a5608a719e62f5207e93de 100644 --- a/services/ans/include/bundle_manager_helper.h +++ b/services/ans/include/bundle_manager_helper.h @@ -86,6 +86,18 @@ public: bool GetDistributedNotificationEnabled(const std::string &bundleName, const int32_t userId); #endif + /** + * @brief Obtains bundle info by bundle name. + * + * @param bundleName Indicates the bundle name. + * @param flag Indicates the bundle flag. + * @param bundleInfo Indicates the bundle info. + * @param userId Indicates the user id. + * @return Returns the check result. + */ + bool GetBundleInfo(const std::string &bundleName, const AppExecFwk::BundleFlag flag, + int32_t userId, AppExecFwk::BundleInfo &bundleInfo); + /** * @brief Obtains BundleInfo of all bundles available in the system through the proxy object. * @param flag Indicates the flag used to specify information contained in the BundleInfo that will be returned. diff --git a/services/ans/include/reminder_config_change_observer.h b/services/ans/include/reminder_config_change_observer.h new file mode 100644 index 0000000000000000000000000000000000000000..0495cf430e46850b6846c3e37c5cb8087683ea1b --- /dev/null +++ b/services/ans/include/reminder_config_change_observer.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_SERVICES_ANS_INCLUDE_REMINDER_CONFIG_CHANGE_OBSERVER_H +#define BASE_NOTIFICATION_DISTRIBUTED_NOTIFICATION_SERVICE_SERVICES_ANS_INCLUDE_REMINDER_CONFIG_CHANGE_OBSERVER_H + +#include "configuration_observer_stub.h" + +namespace OHOS { +namespace Notification { + +/** + * @brief Listening system language change, when the system language changes, + * notify ReminderDataManager. +*/ +class ReminderConfigChangeObserver final : public AppExecFwk::ConfigurationObserverStub { +public: + ReminderConfigChangeObserver() = default; + ~ReminderConfigChangeObserver() = default; + +public: + void OnConfigurationUpdated(const AppExecFwk::Configuration &configuration) override; +}; +} // namespace Notification +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/services/ans/include/reminder_data_manager.h b/services/ans/include/reminder_data_manager.h index 52fbdd48a13912240a8f021f9940801fd2071f40..9d5f197c305fefa952938d689a36819a7b3aa384 100644 --- a/services/ans/include/reminder_data_manager.h +++ b/services/ans/include/reminder_data_manager.h @@ -24,9 +24,11 @@ #ifdef PLAYER_FRAMEWORK_ENABLE #include "player.h" #endif +#include "app_mgr_client.h" #include "reminder_request.h" #include "reminder_store.h" #include "reminder_timer_info.h" +#include "reminder_config_change_observer.h" #include "datashare_predicates.h" #include "datashare_values_bucket.h" @@ -104,6 +106,11 @@ public: void InitUserId(); + /** + * @brief Register configuration observer, the listening system language is changed. + */ + bool RegisterConfigurationObserver(); + void OnUserRemove(const int32_t& userId); void OnServiceStart(); @@ -184,6 +191,24 @@ public: */ void TerminateAlerting(const OHOS::EventFwk::Want &want); + /** + * @brief Get resource manager by handle info. + */ + std::shared_ptr GetBundleResMgr( + const AppExecFwk::BundleInfo &bundleInfo); + + /** + * @brief Update reminders based on the system language. + * + * Update action button title. + */ + void UpdateReminderLanguage(const sptr &reminder); + + /** + * @brief System language change + */ + void OnConfigurationChanged(const AppExecFwk::Configuration &configuration); + static const uint8_t TIME_ZONE_CHANGE; static const uint8_t DATE_TIME_CHANGE; @@ -552,6 +577,11 @@ private: int currentUserId_ {0}; sptr advancedNotificationService_ = nullptr; std::shared_ptr store_ = nullptr; + + /** + * Indicates config change observer for language + */ + sptr configChangeObserver_ = nullptr; }; } // namespace OHOS } // namespace Notification diff --git a/services/ans/src/bundle_manager_helper.cpp b/services/ans/src/bundle_manager_helper.cpp index c6844103592e739898f4339388acedbe3db92d03..71ff872a248753bd5f6f1125252e8f8468033381 100644 --- a/services/ans/src/bundle_manager_helper.cpp +++ b/services/ans/src/bundle_manager_helper.cpp @@ -184,6 +184,24 @@ bool BundleManagerHelper::GetDistributedNotificationEnabled(const std::string &b } #endif +bool BundleManagerHelper::GetBundleInfo(const std::string &bundleName, const AppExecFwk::BundleFlag flag, + int32_t userId, AppExecFwk::BundleInfo &bundleInfo) +{ + std::lock_guard lock(connectionMutex_); + + Connect(); + + if (bundleMgr_ == nullptr) { + return false; + } + int32_t callingUserId; + AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(userId, callingUserId); + std::string identity = IPCSkeleton::ResetCallingIdentity(); + bool ret = bundleMgr_->GetBundleInfo(bundleName, flag, bundleInfo, callingUserId); + IPCSkeleton::SetCallingIdentity(identity); + return ret; +} + bool BundleManagerHelper::GetBundleInfos( const AppExecFwk::BundleFlag flag, std::vector &bundleInfos, int32_t userId) { diff --git a/services/ans/src/reminder_config_change_observer.cpp b/services/ans/src/reminder_config_change_observer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5b68423c8f3fddfb74b49fa03781fbbf696192b0 --- /dev/null +++ b/services/ans/src/reminder_config_change_observer.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "reminder_config_change_observer.h" + +#include "ans_log_wrapper.h" +#include "reminder_data_manager.h" + +namespace OHOS { +namespace Notification { + +void ReminderConfigChangeObserver::OnConfigurationUpdated(const AppExecFwk::Configuration &configuration) +{ + ANSR_LOGD("OnConfigurationUpdated."); + auto reminderDataMgr = ReminderDataManager::GetInstance(); + if (reminderDataMgr == nullptr) { + ANSR_LOGW("Reminder data manager is nullptr"); + return; + } + reminderDataMgr->OnConfigurationChanged(configuration); +} + +} // namespace Notification +} // namespace OHOS diff --git a/services/ans/src/reminder_data_manager.cpp b/services/ans/src/reminder_data_manager.cpp index 514a7db31811ead516713556fa8f45f7d83a7781..f0063614531f2b51ef7aae15da3cade3194d0f87 100644 --- a/services/ans/src/reminder_data_manager.cpp +++ b/services/ans/src/reminder_data_manager.cpp @@ -30,6 +30,8 @@ #include "reminder_event_manager.h" #include "time_service_client.h" #include "singleton.h" +#include "locale_config.h" +#include "bundle_manager_helper.h" #include "datashare_predicates_object.h" #include "datashare_value_object.h" #include "datashare_helper.h" @@ -732,6 +734,7 @@ void ReminderDataManager::UpdateAndSaveReminderLocked( reminder->InitReminderId(); reminder->InitUserId(ReminderRequest::GetUserId(bundleOption->GetUid())); reminder->InitUid(bundleOption->GetUid()); + reminder->InitBundleName(bundleOption->GetBundleName()); if (reminder->GetTriggerTimeInMilli() == ReminderRequest::INVALID_LONG_LONG_VALUE) { ANSR_LOGW("now publish reminder is expired. reminder is =%{public}s", @@ -747,6 +750,7 @@ void ReminderDataManager::UpdateAndSaveReminderLocked( return; } ANSR_LOGD("Containers(vector) add. reminderId=%{public}d", reminderId); + UpdateReminderLanguage(reminder); reminderVector_.push_back(reminder); totalCount_++; store_->UpdateOrInsert(reminder, bundleOption); @@ -1215,6 +1219,11 @@ void ReminderDataManager::Init(bool isFromBootComplete) if (IsReminderAgentReady()) { return; } + // Register config observer for language change + if (!RegisterConfigurationObserver()) { + ANSR_LOGW("Register configuration observer failed."); + return; + } if (store_ == nullptr) { store_ = std::make_shared(); } @@ -1241,6 +1250,27 @@ void ReminderDataManager::InitUserId() } } +bool ReminderDataManager::RegisterConfigurationObserver() +{ + if (configChangeObserver_ != nullptr) { + return true; + } + + auto appMgrClient = std::make_shared(); + if (appMgrClient->ConnectAppMgrService() != ERR_OK) { + ANSR_LOGW("Connect to app mgr service failed."); + return false; + } + + configChangeObserver_ = sptr( + new (std::nothrow) ReminderConfigChangeObserver()); + if (appMgrClient->RegisterConfigurationObserver(configChangeObserver_) != ERR_OK) { + ANSR_LOGE("Register configuration observer failed."); + return false; + } + return true; +} + void ReminderDataManager::GetImmediatelyShowRemindersLocked(std::vector> &reminders) const { std::lock_guard lock(ReminderDataManager::MUTEX); @@ -1598,5 +1628,64 @@ void ReminderDataManager::HandleCustomButtonClick(const OHOS::EventFwk::Want &wa return; } } + +std::shared_ptr ReminderDataManager::GetBundleResMgr( + const AppExecFwk::BundleInfo &bundleInfo) +{ + std::shared_ptr resourceManager(Global::Resource::CreateResourceManager()); + if (!resourceManager) { + ANSR_LOGE("create resourceManager failed."); + return nullptr; + } + // obtains the resource path. + for (const auto &hapModuleInfo : bundleInfo.hapModuleInfos) { + std::string moduleResPath = hapModuleInfo.hapPath.empty() ? hapModuleInfo.resourcePath : hapModuleInfo.hapPath; + if (moduleResPath.empty()) { + continue; + } + ANSR_LOGD("GetBundleResMgr, moduleResPath: %{private}s", moduleResPath.c_str()); + if (!resourceManager->AddResource(moduleResPath.c_str())) { + ANSR_LOGW("GetBundleResMgr AddResource failed"); + } + } + // obtains the current system language. + std::unique_ptr resConfig(Global::Resource::CreateResConfig()); + UErrorCode status = U_ZERO_ERROR; + icu::Locale locale = icu::Locale::forLanguageTag(Global::I18n::LocaleConfig::GetSystemLanguage(), status); + resConfig->SetLocaleInfo(locale); + resourceManager->UpdateResConfig(*resConfig); + return resourceManager; +} + +void ReminderDataManager::UpdateReminderLanguage(const sptr &reminder) +{ + // obtains the bundle info by bundle name + const std::string bundleName = reminder->GetBundleName(); + AppExecFwk::BundleInfo bundleInfo; + if (!BundleManagerHelper::GetInstance()->GetBundleInfo(bundleName, + AppExecFwk::BundleFlag::GET_BUNDLE_WITH_ABILITIES, reminder->GetUid(), bundleInfo)) { + ANSR_LOGE("Get reminder request[%{public}d][%{public}s] bundle info failed.", + reminder->GetReminderId(), bundleName.c_str()); + return; + } + // obtains the resource manager + auto resourceMgr = GetBundleResMgr(bundleInfo); + if (resourceMgr == nullptr) { + ANSR_LOGE("Get reminder request[%{public}d][%{public}s] resource manager failed.", + reminder->GetReminderId(), bundleName.c_str()); + return; + } + // update action button title + reminder->OnLanguageChange(resourceMgr); +} + +void ReminderDataManager::OnConfigurationChanged(const AppExecFwk::Configuration &configuration) +{ + ANSR_LOGI("System language config changed."); + std::lock_guard lock(ReminderDataManager::MUTEX); + for (auto it = reminderVector_.begin(); it != reminderVector_.end(); ++it) { + UpdateReminderLanguage(*it); + } +} } } diff --git a/test/fuzztest/reminderrequest_fuzzer/reminderrequest_fuzzer.cpp b/test/fuzztest/reminderrequest_fuzzer/reminderrequest_fuzzer.cpp index c5ab30198fdf9344b0a61be8cacca18bd260b268..1b5cd73e955447110fcc26ff75536dc20bfaa45a 100644 --- a/test/fuzztest/reminderrequest_fuzzer/reminderrequest_fuzzer.cpp +++ b/test/fuzztest/reminderrequest_fuzzer/reminderrequest_fuzzer.cpp @@ -38,7 +38,7 @@ namespace OHOS { uint8_t types = *data % ACTION_BUTTON_TYPE; Notification::ReminderRequest::ActionButtonType type = Notification::ReminderRequest::ActionButtonType(types); - reminderRequest.SetActionButton(stringData, type); + reminderRequest.SetActionButton(stringData, type, stringData); reminderRequest.SetContent(stringData); reminderRequest.SetExpiredContent(stringData); bool enabled = *data % ENABLE;