• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #include "base/resource/shared_image_manager.h"
17 
18 #include <cstdint>
19 #include <type_traits>
20 #include <utility>
21 
22 #include "base/log/log.h"
23 #include "base/thread/cancelable_callback.h"
24 #include "base/utils/utils.h"
25 
26 namespace OHOS::Ace {
27 namespace {
28 
29 constexpr uint32_t DELAY_TIME_FOR_IMAGE_DATA_CLEAN = 30000;
30 constexpr char MEMORY_IMAGE_HEAD[] = "memory://";
31 
32 } // namespace
33 
GenerateClearImageDataCallback(const std::string & name,size_t dataSize)34 std::function<void()> SharedImageManager::GenerateClearImageDataCallback(const std::string& name, size_t dataSize)
35 {
36     auto clearImageDataCallback = [wp = AceType::WeakClaim(this), picName = name, dataSize]() {
37         auto sharedImageManager = wp.Upgrade();
38         if (!sharedImageManager) {
39             return;
40         }
41         {
42             std::lock_guard<std::mutex> lockImageMap(sharedImageManager->sharedImageMapMutex_);
43             sharedImageManager->sharedImageMap_.erase(picName);
44         }
45         {
46             std::lock_guard<std::mutex> lockCancelableCallbackMap_(sharedImageManager->cancelableCallbackMapMutex_);
47             sharedImageManager->cancelableCallbackMap_.erase(picName);
48         }
49         LOGI("Done clean image data for %{private}s, data size is %{public}zu", picName.c_str(), dataSize);
50     };
51     return clearImageDataCallback;
52 }
53 
PostDelayedTaskToClearImageData(const std::string & name,size_t dataSize)54 void SharedImageManager::PostDelayedTaskToClearImageData(const std::string& name, size_t dataSize)
55 {
56     auto taskExecutor = taskExecutor_.Upgrade();
57     CHECK_NULL_VOID(taskExecutor);
58     std::lock_guard<std::mutex> lockCancelableCallbackMap_(cancelableCallbackMapMutex_);
59     auto& cancelableCallback = cancelableCallbackMap_[name];
60     cancelableCallback.Reset(GenerateClearImageDataCallback(name, dataSize));
61     taskExecutor->PostDelayedTask(cancelableCallback, TaskExecutor::TaskType::BACKGROUND,
62         DELAY_TIME_FOR_IMAGE_DATA_CLEAN);
63 }
64 
AddSharedImage(const std::string & name,SharedImage && sharedImage)65 void SharedImageManager::AddSharedImage(const std::string& name, SharedImage&& sharedImage)
66 {
67         std::set<WeakPtr<ImageProviderLoader>> providerWpSet = std::set<WeakPtr<ImageProviderLoader>>();
68         // step1: lock provider map to search for record of current picture name
69         std::scoped_lock lock(providerMapMutex_, sharedImageMapMutex_);
70         auto providersToNotify = providerMapToReload_.find(name);
71         if (providersToNotify != providerMapToReload_.end()) {
72             for (const auto& providerWp : providersToNotify->second) {
73                 auto provider = providerWp.Upgrade();
74                 if (!provider) {
75                     LOGE("provider of %{private}s is null, data size is %{public}zu", name.c_str(), sharedImage.size());
76                     continue;
77                 }
78                 providerWpSet.emplace(provider);
79             }
80             providerMapToReload_.erase(providersToNotify);
81         }
82         // step2: lock image map to add shared image and notify [LazyMemoryImageProvider]s to update data and reload
83         // update image data when the name can be found in map
84         auto iter = sharedImageMap_.find(name);
85         if (iter != sharedImageMap_.end()) {
86             iter->second = std::move(sharedImage);
87         } else {
88             sharedImageMap_.emplace(name, std::move(sharedImage));
89         }
90         auto taskExecutor = taskExecutor_.Upgrade();
91         CHECK_NULL_VOID(taskExecutor);
92         taskExecutor->PostTask(
93             [providerWpSet, name, wp = AceType::WeakClaim(this)]() {
94                 auto sharedImageManager = wp.Upgrade();
95                 CHECK_NULL_VOID(sharedImageManager);
96                 size_t dataSize = 0;
97                 auto sharedImageMap = sharedImageManager->GetSharedImageMap();
98                 {
99                     std::lock_guard<std::mutex> lockImageMap(sharedImageManager->sharedImageMapMutex_);
100                     auto imageDataIter = sharedImageMap.find(name);
101                     if (imageDataIter == sharedImageMap.end()) {
102                         LOGE("fail to find data of %{public}s in sharedImageMap, stop UpdateData", name.c_str());
103                         return;
104                     }
105                     dataSize = imageDataIter->second.size();
106                     for (const auto& providerWp : providerWpSet) {
107                         auto provider = providerWp.Upgrade();
108                         if (!provider) {
109                             LOGE("provider of %{public}s is null when UpdateData, dataSize is %{public}zu",
110                                 name.c_str(), dataSize);
111                             continue;
112                         }
113                         provider->UpdateData(std::string(MEMORY_IMAGE_HEAD).append(name), imageDataIter->second);
114                     }
115                     LOGI("done add image data for %{private}s, length of data is %{public}zu", name.c_str(), dataSize);
116                 }
117                 sharedImageManager->PostDelayedTaskToClearImageData(name, dataSize);
118             },
119             TaskExecutor::TaskType::UI);
120 }
121 
AddPictureNamesToReloadMap(std::string && name)122 void SharedImageManager::AddPictureNamesToReloadMap(std::string&& name)
123 {
124     // add names of memory image to be read from shared memory
125     std::lock_guard<std::mutex> lock(providerMapMutex_);
126     providerMapToReload_.try_emplace(name, std::set<WeakPtr<ImageProviderLoader>>());
127 }
128 
FindImageInSharedImageMap(const std::string & name,const WeakPtr<ImageProviderLoader> & providerWp)129 bool SharedImageManager::FindImageInSharedImageMap(
130     const std::string& name, const WeakPtr<ImageProviderLoader>& providerWp)
131 {
132     auto loader = providerWp.Upgrade();
133     if (!loader) {
134         LOGE("provider of %{private}s is null", name.c_str());
135         return false;
136     }
137     std::lock_guard<std::mutex> lockImageMap(sharedImageMapMutex_);
138     auto iter = sharedImageMap_.find(name);
139     if (iter == sharedImageMap_.end()) {
140         LOGE("image data of %{private}s does not found in SharedImageMap", name.c_str());
141         return false;
142     }
143     loader->UpdateData(std::string(MEMORY_IMAGE_HEAD).append(name), iter->second);
144     return true;
145 }
146 
RegisterLoader(const std::string & name,const WeakPtr<ImageProviderLoader> & providerWp)147 bool SharedImageManager::RegisterLoader(const std::string& name, const WeakPtr<ImageProviderLoader>& providerWp)
148 {
149     std::lock_guard<std::mutex> lockProviderMap(providerMapMutex_);
150     bool resourceInMap = (providerMapToReload_.find(name) != providerMapToReload_.end());
151     providerMapToReload_[name].emplace(providerWp);
152     return resourceInMap;
153 }
154 
Remove(const std::string & name)155 bool SharedImageManager::Remove(const std::string& name)
156 {
157     int res = static_cast<int>(sharedImageMap_.erase(name));
158     return (res != 0);
159 }
160 } // namespace OHOS::Ace
161