• 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     };
50     return clearImageDataCallback;
51 }
52 
PostDelayedTaskToClearImageData(const std::string & name,size_t dataSize)53 void SharedImageManager::PostDelayedTaskToClearImageData(const std::string& name, size_t dataSize)
54 {
55     auto taskExecutor = taskExecutor_.Upgrade();
56     CHECK_NULL_VOID(taskExecutor);
57     std::lock_guard<std::mutex> lockCancelableCallbackMap_(cancelableCallbackMapMutex_);
58     auto& cancelableCallback = cancelableCallbackMap_[name];
59     cancelableCallback.Reset(GenerateClearImageDataCallback(name, dataSize));
60     auto bkTask = [wp = taskExecutor_, cancelableCallback]() {
61         auto taskExecutor = wp.Upgrade();
62         CHECK_NULL_VOID(taskExecutor);
63         taskExecutor->PostTask(cancelableCallback, TaskExecutor::TaskType::BACKGROUND);
64     };
65     taskExecutor->PostDelayedTask(bkTask, TaskExecutor::TaskType::UI, DELAY_TIME_FOR_IMAGE_DATA_CLEAN);
66 }
67 
AddSharedImage(const std::string & name,SharedImage && sharedImage)68 void SharedImageManager::AddSharedImage(const std::string& name, SharedImage&& sharedImage)
69 {
70         std::set<WeakPtr<ImageProviderLoader>> providerWpSet = std::set<WeakPtr<ImageProviderLoader>>();
71         // step1: lock provider map to search for record of current picture name
72         std::scoped_lock lock(providerMapMutex_, sharedImageMapMutex_);
73         auto providersToNotify = providerMapToReload_.find(name);
74         if (providersToNotify != providerMapToReload_.end()) {
75             for (const auto& providerWp : providersToNotify->second) {
76                 auto provider = providerWp.Upgrade();
77                 if (!provider) {
78                     continue;
79                 }
80                 providerWpSet.emplace(provider);
81             }
82             providerMapToReload_.erase(providersToNotify);
83         }
84         // step2: lock image map to add shared image and notify [LazyMemoryImageProvider]s to update data and reload
85         // update image data when the name can be found in map
86         auto iter = sharedImageMap_.find(name);
87         if (iter != sharedImageMap_.end()) {
88             iter->second = std::move(sharedImage);
89         } else {
90             sharedImageMap_.emplace(name, std::move(sharedImage));
91         }
92         auto taskExecutor = taskExecutor_.Upgrade();
93         CHECK_NULL_VOID(taskExecutor);
94         taskExecutor->PostTask(
95             [providerWpSet, name, wp = AceType::WeakClaim(this)]() {
96                 auto sharedImageManager = wp.Upgrade();
97                 CHECK_NULL_VOID(sharedImageManager);
98                 size_t dataSize = 0;
99                 auto sharedImageMap = sharedImageManager->GetSharedImageMap();
100                 {
101                     std::lock_guard<std::mutex> lockImageMap(sharedImageManager->sharedImageMapMutex_);
102                     auto imageDataIter = sharedImageMap.find(name);
103                     if (imageDataIter == sharedImageMap.end()) {
104                         LOGW("fail to find data of %{public}s in sharedImageMap, stop UpdateData", name.c_str());
105                         return;
106                     }
107                     dataSize = imageDataIter->second.size();
108                     for (const auto& providerWp : providerWpSet) {
109                         auto provider = providerWp.Upgrade();
110                         if (!provider) {
111                             continue;
112                         }
113                         provider->UpdateData(std::string(MEMORY_IMAGE_HEAD).append(name), imageDataIter->second);
114                     }
115                 }
116                 sharedImageManager->PostDelayedTaskToClearImageData(name, dataSize);
117             },
118             TaskExecutor::TaskType::UI);
119 }
120 
AddPictureNamesToReloadMap(std::string && name)121 void SharedImageManager::AddPictureNamesToReloadMap(std::string&& name)
122 {
123     // add names of memory image to be read from shared memory
124     std::lock_guard<std::mutex> lock(providerMapMutex_);
125     providerMapToReload_.try_emplace(name, std::set<WeakPtr<ImageProviderLoader>>());
126 }
127 
FindImageInSharedImageMap(const std::string & name,const WeakPtr<ImageProviderLoader> & providerWp)128 bool SharedImageManager::FindImageInSharedImageMap(
129     const std::string& name, const WeakPtr<ImageProviderLoader>& providerWp)
130 {
131     auto loader = providerWp.Upgrade();
132     if (!loader) {
133         return false;
134     }
135     std::lock_guard<std::mutex> lockImageMap(sharedImageMapMutex_);
136     auto iter = sharedImageMap_.find(name);
137     if (iter == sharedImageMap_.end()) {
138         LOGW("image data of %{private}s does not found in SharedImageMap", name.c_str());
139         return false;
140     }
141     loader->UpdateData(std::string(MEMORY_IMAGE_HEAD).append(name), iter->second);
142     return true;
143 }
144 
RegisterLoader(const std::string & name,const WeakPtr<ImageProviderLoader> & providerWp)145 bool SharedImageManager::RegisterLoader(const std::string& name, const WeakPtr<ImageProviderLoader>& providerWp)
146 {
147     std::lock_guard<std::mutex> lockProviderMap(providerMapMutex_);
148     bool resourceInMap = (providerMapToReload_.find(name) != providerMapToReload_.end());
149     providerMapToReload_[name].emplace(providerWp);
150     return resourceInMap;
151 }
152 
Remove(const std::string & name)153 bool SharedImageManager::Remove(const std::string& name)
154 {
155     int res = static_cast<int>(sharedImageMap_.erase(name));
156     return (res != 0);
157 }
158 } // namespace OHOS::Ace
159