1 /* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMMON_RESOURCE_RESOURCE_MANAGER_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMMON_RESOURCE_RESOURCE_MANAGER_H 18 19 #include <climits> 20 #include <functional> 21 #include <map> 22 #include <mutex> 23 #include <shared_mutex> 24 #include <string> 25 #include <utility> 26 27 #include "base/memory/ace_type.h" 28 #include "base/memory/referenced.h" 29 #include "base/utils/resource_configuration.h" 30 #include "core/common/resource/resource_object.h" 31 #include "core/components/theme/resource_adapter.h" 32 #include "core/common/lru/count_limit_lru.h" 33 34 namespace OHOS::Ace { 35 constexpr char DEFAULT_RESOURCE_KEY[] = ""; 36 37 class ACE_FORCE_EXPORT ResourceManager final : public AceType { 38 DECLARE_ACE_TYPE(ResourceManager, AceType); 39 40 public: 41 ~ResourceManager() = default; 42 43 static ResourceManager& GetInstance(); 44 45 RefPtr<ResourceAdapter> GetOrCreateResourceAdapter(RefPtr<ResourceObject>& resourceObject); 46 MakeCacheKey(const std::string & bundleName,const std::string & moduleName)47 std::string MakeCacheKey(const std::string& bundleName, const std::string& moduleName) 48 { 49 if (bundleName.empty() && moduleName.empty()) { 50 return DEFAULT_RESOURCE_KEY; 51 } 52 return bundleName + "." + moduleName; 53 } 54 55 void AddResourceAdapter(const std::string& bundleName, const std::string& moduleName, 56 RefPtr<ResourceAdapter>& resourceAdapter, bool replace = false) 57 { 58 std::unique_lock<std::shared_mutex> lock(mutex_); 59 if (bundleName.empty() && moduleName.empty()) { 60 resourceAdapters_[DEFAULT_RESOURCE_KEY] = resourceAdapter; 61 } else { 62 auto key = MakeCacheKey(bundleName, moduleName); 63 if (replace) { 64 CountLimitLRU::RemoveCacheObjFromCountLimitLRU<RefPtr<ResourceAdapter>>(key, cacheList_, cache_); 65 } 66 CountLimitLRU::CacheWithCountLimitLRU<RefPtr<ResourceAdapter>>( 67 key, resourceAdapter, cacheList_, cache_, capacity_); 68 } 69 } 70 IsResourceAdapterRecord(const std::string & bundleName,const std::string & moduleName)71 bool IsResourceAdapterRecord(const std::string& bundleName, const std::string& moduleName) 72 { 73 std::shared_lock<std::shared_mutex> lock(mutex_); 74 auto key = MakeCacheKey(bundleName, moduleName); 75 if (resourceAdapters_.find(key) != resourceAdapters_.end()) { 76 return true; 77 } 78 return cache_.find(key) != cache_.end(); 79 } 80 GetResourceAdapter(const std::string & bundleName,const std::string & moduleName)81 RefPtr<ResourceAdapter> GetResourceAdapter(const std::string& bundleName, const std::string& moduleName) 82 { 83 std::unique_lock<std::shared_mutex> lock(mutex_); 84 auto key = MakeCacheKey(bundleName, moduleName); 85 auto mapIter = resourceAdapters_.find(key); 86 if (mapIter != resourceAdapters_.end()) { 87 return mapIter->second; 88 } else if (key == DEFAULT_RESOURCE_KEY) { 89 TAG_LOGW(AceLogTag::ACE_RESOURCE, 90 "Get default resourceAdapter failed, don't get resource while UIContent not initialized yet"); 91 return ResourceAdapter::Create(); 92 } 93 94 auto resAdapter = CountLimitLRU::GetCacheObjWithCountLimitLRU<RefPtr<ResourceAdapter>>(key, cacheList_, cache_); 95 if (resAdapter != nullptr) { 96 return resAdapter; 97 } 98 99 return nullptr; 100 } 101 GetResourceAdapter()102 RefPtr<ResourceAdapter> GetResourceAdapter() 103 { 104 std::shared_lock<std::shared_mutex> lock(mutex_); 105 auto key = MakeCacheKey("", ""); 106 return resourceAdapters_.at(key); 107 } 108 109 void UpdateResourceConfig(const ResourceConfiguration& config, bool themeFlag = false) 110 { 111 std::unique_lock<std::shared_mutex> lock(mutex_); 112 for (auto iter = resourceAdapters_.begin(); iter != resourceAdapters_.end(); ++iter) { 113 iter->second->UpdateConfig(config, themeFlag); 114 } 115 for (auto iter = cacheList_.begin(); iter != cacheList_.end(); ++iter) { 116 iter->cacheObj->UpdateConfig(config, themeFlag); 117 } 118 } 119 RemoveResourceAdapter(const std::string & bundleName,const std::string & moduleName)120 void RemoveResourceAdapter(const std::string& bundleName, const std::string& moduleName) 121 { 122 std::unique_lock<std::shared_mutex> lock(mutex_); 123 std::string key = MakeCacheKey(bundleName, moduleName); 124 if (resourceAdapters_.find(key) != resourceAdapters_.end()) { 125 resourceAdapters_.erase(key); 126 } 127 if (!bundleName.empty() && !moduleName.empty()) { 128 CountLimitLRU::RemoveCacheObjFromCountLimitLRU<RefPtr<ResourceAdapter>>(key, cacheList_, cache_); 129 } 130 } 131 Reset()132 void Reset() 133 { 134 std::unique_lock<std::shared_mutex> lock(mutex_); 135 cacheList_.clear(); 136 cache_.clear(); 137 TAG_LOGI(AceLogTag::ACE_RESOURCE, "The cache of Resource has been released!"); 138 } 139 UpdateColorMode(ColorMode colorMode)140 void UpdateColorMode(ColorMode colorMode) 141 { 142 std::unique_lock<std::shared_mutex> lock(mutex_); 143 for (auto iter = resourceAdapters_.begin(); iter != resourceAdapters_.end(); ++iter) { 144 iter->second->UpdateColorMode(colorMode); 145 } 146 for (auto iter = cacheList_.begin(); iter != cacheList_.end(); ++iter) { 147 iter->cacheObj->UpdateColorMode(colorMode); 148 } 149 } 150 151 void RegisterMainResourceAdapter( 152 const std::string& bundleName, const std::string& moduleName, const RefPtr<ResourceAdapter>& resAdapter); 153 154 private: 155 ResourceManager() = default; 156 157 std::unordered_map<std::string, RefPtr<ResourceAdapter>> resourceAdapters_; 158 std::shared_mutex mutex_; 159 160 std::atomic<size_t> capacity_ = 3; 161 std::list<CacheNode<RefPtr<ResourceAdapter>>> cacheList_; 162 std::unordered_map<std::string, std::list<CacheNode<RefPtr<ResourceAdapter>>>::iterator> cache_; 163 }; 164 } // namespace OHOS::Ace 165 166 #endif