• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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_COMPONENTS_NG_IMAGE_PROVIDER_IMAGE_LOADING_CONTEXT_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_IMAGE_PROVIDER_IMAGE_LOADING_CONTEXT_H
18 
19 #include <cstdint>
20 #include "base/geometry/ng/size_t.h"
21 #include "base/thread/task_executor.h"
22 #include "core/components/common/layout/constants.h"
23 #include "core/components_ng/image_provider/image_object.h"
24 #include "core/components_ng/image_provider/image_provider.h"
25 #include "core/components_ng/image_provider/image_state_manager.h"
26 
27 namespace OHOS::Ace::NG {
28 
29 using PendingMakeCanvasImageTask = std::function<void()>;
30 // [ImageLoadingContext] do two things:
31 // 1. Provide interfaces for who owns it, notify it's owner when loading events come.
32 // 2. Drive [ImageObject] to load and make [CanvasImage].
33 class ACE_FORCE_EXPORT ImageLoadingContext : public AceType {
34     DECLARE_ACE_TYPE(ImageLoadingContext, AceType);
35 
36 public:
37     // Create an empty ImageObject and initialize state machine when the constructor is called
38     ImageLoadingContext(const ImageSourceInfo& src, LoadNotifier&& loadNotifier, bool syncLoad = false);
39     ~ImageLoadingContext() override;
40 
41     // return true if calling MakeCanvasImage is necessary
42     bool MakeCanvasImageIfNeed(const SizeF& dstSize, bool autoResize, ImageFit imageFit,
43         const std::optional<SizeF>& sourceSize = std::nullopt, bool hasValidSlice = false);
44 
45     /* interfaces to drive image loading */
46     void LoadImageData();
47     void MakeCanvasImage(const SizeF& dstSize, bool needResize, ImageFit imageFit = ImageFit::COVER,
48         const std::optional<SizeF>& sourceSize = std::nullopt);
49     void ResetLoading();
50     void ResumeLoading();
51 
52     /* interfaces to get properties */
53     SizeF GetImageSize() const;
54     const RectF& GetDstRect() const;
55     const RectF& GetSrcRect() const;
56     ImageFit GetImageFit() const;
57     int32_t GetFrameCount() const;
58 
59     RefPtr<CanvasImage> MoveCanvasImage();
60     RefPtr<ImageObject> MoveImageObject();
GetImageObject()61     RefPtr<ImageObject> GetImageObject()
62     {
63         return imageObj_;
64     }
65 
66     const ImageSourceInfo& GetSourceInfo() const;
67     const SizeF& GetDstSize() const;
68     bool GetAutoResize() const;
69     std::optional<SizeF> GetSourceSize() const;
70     bool NeedAlt() const;
71     const std::optional<Color>& GetSvgFillColor() const;
72 
73     /* interfaces to set properties */
74     void SetImageFit(ImageFit imageFit);
75     void SetAutoResize(bool needResize);
76     void SetSourceSize(const std::optional<SizeF>& sourceSize = std::nullopt);
GetSrc()77     const ImageSourceInfo GetSrc() const
78     {
79         return src_;
80     }
81 
GetStateManger()82     const RefPtr<ImageStateManager>& GetStateManger()
83     {
84         return stateManager_;
85     }
86 
87     // callbacks that will be called by ImageProvider when load process finishes
88     void DataReadyCallback(const RefPtr<ImageObject>& imageObj);
89     void SuccessCallback(const RefPtr<CanvasImage>& canvasImage);
90     void FailCallback(const std::string& errorMsg);
91     const std::string GetCurrentLoadingState();
92     void ResizableCalcDstSize();
93     // Needed to restore the relevant containerId from the originating thread
GetContainerId()94     int32_t GetContainerId()
95     {
96         return containerId_;
97     }
98     void DownloadImage();
99     void PerformDownload();
100     void CacheDownloadedImage();
101     bool Downloadable();
102     void OnDataReady();
103     bool RemoveDownloadTask(const std::string& src);
104 
FinishMearuse()105     void FinishMearuse()
106     {
107         measureFinish_ = true;
108     }
109 
110     void CallbackAfterMeasureIfNeed();
111 
112     void OnDataReadyOnCompleteCallBack();
113     void SetOnProgressCallback(std::function<void(const uint32_t& dlNow, const uint32_t& dlTotal)>&& onProgress);
114 
SetDynamicRangeMode(DynamicRangeMode dynamicMode)115     void SetDynamicRangeMode(DynamicRangeMode dynamicMode)
116     {
117         dynamicMode_ = dynamicMode;
118     }
119 
SetIsHdrDecoderNeed(bool isHdrDecoderNeed)120     void SetIsHdrDecoderNeed(bool isHdrDecoderNeed)
121     {
122         isHdrDecoderNeed_ = isHdrDecoderNeed;
123     }
124 
GetIsHdrDecoderNeed()125     bool GetIsHdrDecoderNeed()
126     {
127         return isHdrDecoderNeed_;
128     }
129 
GetDynamicRangeMode()130     DynamicRangeMode GetDynamicRangeMode()
131     {
132         return dynamicMode_;
133     }
134 
SetImageQuality(AIImageQuality imageQuality)135     void SetImageQuality(AIImageQuality imageQuality)
136     {
137         imageQuality_ = imageQuality;
138     }
139 
GetImageQuality()140     AIImageQuality GetImageQuality()
141     {
142         return imageQuality_;
143     }
144 
GetLoadInVipChannel()145     bool GetLoadInVipChannel()
146     {
147         return loadInVipChannel_;
148     }
149 
SetLoadInVipChannel(bool loadInVipChannel)150     void SetLoadInVipChannel(bool loadInVipChannel)
151     {
152         loadInVipChannel_ = loadInVipChannel;
153     }
154 
GetErrorMsg()155     const std::string& GetErrorMsg()
156     {
157         return errorMsg_;
158     }
159 
SetNodeId(int32_t nodeId)160     void SetNodeId(int32_t nodeId)
161     {
162         nodeId_ = nodeId;
163     }
164 
165 private:
166 #define DEFINE_SET_NOTIFY_TASK(loadResult)                                            \
167     void Set##loadResult##NotifyTask(loadResult##NotifyTask&& loadResult##NotifyTask) \
168     {                                                                                 \
169         notifiers_.on##loadResult##_ = std::move(loadResult##NotifyTask);             \
170     }
171 
172     // classes that use [ImageLoadingContext] can register three notify tasks to do things
173     DEFINE_SET_NOTIFY_TASK(DataReady);
174     DEFINE_SET_NOTIFY_TASK(LoadSuccess);
175     DEFINE_SET_NOTIFY_TASK(LoadFail);
176 
177     // tasks that run when entering a new state
178     void OnUnloaded();
179     void OnDataLoading();
180     void OnMakeCanvasImage();
181     void OnLoadSuccess();
182     void OnLoadFail();
183     bool NotifyReadyIfCacheHit();
184     void DownloadImageSuccess(const std::string& imageData);
185     void DownloadImageFailed(const std::string& errorMessage);
186     void DownloadOnProgress(const uint32_t& dlNow, const uint32_t& dlTotal);
187     // round up int to the nearest 2-fold proportion of image width
188     // REQUIRE: value > 0, image width > 0
189     int32_t RoundUp(int32_t value);
190     static SizeF CalculateTargetSize(const SizeF& srcSize, const SizeF& dstSize, const SizeF& rawImageSize);
191 
SizeChanging(const SizeF & dstSize)192     inline bool SizeChanging(const SizeF& dstSize)
193     {
194         return dstSize_.IsPositive() && dstSize != dstSize_;
195     }
196 
197     ImageSourceInfo src_;
198     RefPtr<ImageStateManager> stateManager_;
199     RefPtr<ImageObject> imageObj_;
200     RefPtr<CanvasImage> canvasImage_;
201     std::string downloadedUrlData_;
202 
203     // [LoadNotifier] contains 3 tasks to notify whom uses [ImageLoadingContext] of loading results
204     LoadNotifier notifiers_;
205 
206     // the container of the creator thread of this image loading context
207     const int32_t containerId_ {0};
208 
209     bool autoResize_ = true;
210     bool syncLoad_ = false;
211     bool isHdrDecoderNeed_ = false;
212     bool loadInVipChannel_ = false;
213 
214     DynamicRangeMode dynamicMode_ = DynamicRangeMode::STANDARD;
215     AIImageQuality imageQuality_ = AIImageQuality::NONE;
216 
217     RectF srcRect_;
218     RectF dstRect_;
219     SizeF dstSize_;
220     std::atomic<bool> measureFinish_ = false;
221     std::atomic<bool> needErrorCallBack_ = false;
222     std::atomic<bool> needDataReadyCallBack_ = false;
223     // to determine whether the image needs to be reloaded
224     int32_t sizeLevel_ = -1;
225     int32_t nodeId_ = -1;
226 
227     ImageFit imageFit_ = ImageFit::COVER;
228     std::unique_ptr<SizeF> sourceSizePtr_ = nullptr;
229     std::function<void()> updateParamsCallback_ = nullptr;
230 
231     std::string errorMsg_;
232     // to cancel MakeCanvasImage task
233     std::string canvasKey_;
234 
235     bool firstLoadImage_ = true;
236 
237     // if another makeCanvasImage task arrives and current state cannot handle makeCanvasImage command,
238     // save the least recent makeCanvasImage task and trigger it when the previous makeCanvasImage task end
239     // and state becomes MAKE_CANVAS_IMAGE_SUCCESS
240     PendingMakeCanvasImageTask pendingMakeCanvasImageTask_ = nullptr;
241 
242     friend class ImageStateManager;
243     ACE_DISALLOW_COPY_AND_MOVE(ImageLoadingContext);
244 
245     std::function<void(const uint32_t& dlNow, const uint32_t& dlTotal)> onProgressCallback_ = nullptr;
246 };
247 
248 } // namespace OHOS::Ace::NG
249 
250 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_IMAGE_PROVIDER_IMAGE_LOADING_CONTEXT_H
251