• 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 "base/log/log.h"
19 
20 namespace OHOS::Ace {
21 namespace {
22 
23 constexpr uint32_t DELAY_TIME_FOR_IMAGE_DATA_CLEAN = 30000;
24 constexpr char MEMORY_IMAGE_HEAD[] = "memory://";
25 
26 } // namespace
27 
GenerateClearImageDataCallback(const std::string & name,size_t dataSize)28 std::function<void()> SharedImageManager::GenerateClearImageDataCallback(const std::string& name, size_t dataSize)
29 {
30     auto clearImageDataCallback = [wp = AceType::WeakClaim(this), picName = name, dataSize]() {
31         auto sharedImageManager = wp.Upgrade();
32         if (!sharedImageManager) {
33             return;
34         }
35         {
36             std::lock_guard<std::mutex> lockImageMap(sharedImageManager->sharedImageMapMutex_);
37             sharedImageManager->sharedImageMap_.erase(picName);
38         }
39         {
40             std::lock_guard<std::mutex> lockCancelableCallbackMap_(sharedImageManager->cancelableCallbackMapMutex_);
41             sharedImageManager->cancelableCallbackMap_.erase(picName);
42         }
43         LOGI("Done clean image data for %{private}s, data size is %{public}zu", picName.c_str(), dataSize);
44     };
45     return clearImageDataCallback;
46 }
47 
PostDelayedTaskToClearImageData(const std::string & name,size_t dataSize)48 void SharedImageManager::PostDelayedTaskToClearImageData(const std::string& name, size_t dataSize)
49 {
50     if (!taskExecutor_) {
51         LOGE("taskExecutor is null!");
52         return;
53     }
54     std::lock_guard<std::mutex> lockCancelableCallbackMap_(cancelableCallbackMapMutex_);
55     auto& cancelableCallback = cancelableCallbackMap_[name];
56     cancelableCallback.Reset(GenerateClearImageDataCallback(name, dataSize));
57     taskExecutor_->PostDelayedTask(cancelableCallback, TaskExecutor::TaskType::IO, DELAY_TIME_FOR_IMAGE_DATA_CLEAN);
58 }
59 
AddSharedImage(const std::string & name,SharedImage && sharedImage)60 void SharedImageManager::AddSharedImage(const std::string& name, SharedImage&& sharedImage)
61 {
62     size_t dataSize = 0;
63     {
64         std::set<RefPtr<ImageProviderLoader>> providerSet = std::set<RefPtr<ImageProviderLoader>>();
65         // step1: lock provider map to search for record of current picture name
66         std::scoped_lock lock(providerMapMutex_, sharedImageMapMutex_);
67         auto providersToNotify = providerMapToReload_.find(name);
68         if (providersToNotify != providerMapToReload_.end()) {
69             for (const auto& providerWp : providersToNotify->second) {
70                 auto provider = providerWp.Upgrade();
71                 if (!provider) {
72                     LOGE("provider of %{private}s is null, data size is %{public}zu", name.c_str(), sharedImage.size());
73                     continue;
74                 }
75                 providerSet.emplace(provider);
76             }
77             providerMapToReload_.erase(providersToNotify);
78         }
79         // step2: lock image map to add shared image and notify [LazyMemoryImageProvider]s to update data and reload
80         // update image data when the name can be found in map
81         auto result = sharedImageMap_.try_emplace(name, std::move(sharedImage));
82         if (!result.second) {
83             result.first->second = std::move(sharedImage);
84         }
85         for (const auto& provider : providerSet) {
86             provider->UpdateData(std::string(MEMORY_IMAGE_HEAD).append(name), result.first->second);
87         }
88         dataSize = result.first->second.size();
89         LOGI("done add image data for %{private}s, length of data is %{public}zu", name.c_str(), dataSize);
90     }
91     PostDelayedTaskToClearImageData(name, dataSize);
92 }
93 
AddPictureNamesToReloadMap(std::string && name)94 void SharedImageManager::AddPictureNamesToReloadMap(std::string&& name)
95 {
96     // add names of memory image to be read from shared memory
97     std::lock_guard<std::mutex> lock(providerMapMutex_);
98     providerMapToReload_.try_emplace(name, std::set<WeakPtr<ImageProviderLoader>>());
99 }
100 
AddProviderToReloadMap(const std::string & name,const WeakPtr<ImageProviderLoader> & loaderWp)101 bool SharedImageManager::AddProviderToReloadMap(
102     const std::string& name, const WeakPtr<ImageProviderLoader>& loaderWp)
103 {
104     std::lock_guard<std::mutex> lock(providerMapMutex_);
105     auto providerMapIter = providerMapToReload_.find(name);
106     if (providerMapIter != providerMapToReload_.end()) {
107         providerMapIter->second.emplace(loaderWp);
108         return true;
109     }
110     return false;
111 }
112 
FindImageInSharedImageMap(const std::string & name,const WeakPtr<ImageProviderLoader> & providerWp)113 bool SharedImageManager::FindImageInSharedImageMap(
114     const std::string& name, const WeakPtr<ImageProviderLoader>& providerWp)
115 {
116     auto loader = providerWp.Upgrade();
117     if (!loader) {
118         LOGE("provider of %{private}s is null", name.c_str());
119         return false;
120     }
121     std::lock_guard<std::mutex> lockImageMap(sharedImageMapMutex_);
122     auto iter = sharedImageMap_.find(name);
123     if (iter == sharedImageMap_.end()) {
124         LOGE("image data of %{private}s does not found in SharedImageMap", name.c_str());
125         return false;
126     }
127     loader->UpdateData(std::string(MEMORY_IMAGE_HEAD).append(name), iter->second);
128     return true;
129 }
130 
131 } // namespace OHOS::Ace
132