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 INTERFACES_KITS_JS_MEDIALIBRARY_INCLUDE_THUMBNAIL_MANAGER_H
17 #define INTERFACES_KITS_JS_MEDIALIBRARY_INCLUDE_THUMBNAIL_MANAGER_H
18 
19 #include <condition_variable>
20 #include <list>
21 #include <memory>
22 #include <mutex>
23 #include <string>
24 #include <thread>
25 
26 #include "image_type.h"
27 #include "napi/native_api.h"
28 #include "nocopyable.h"
29 #include "safe_map.h"
30 #include "safe_queue.h"
31 #include "pixel_map.h"
32 #include "unique_fd.h"
33 #include "userfile_manager_types.h"
34 
35 namespace OHOS {
36 namespace Media {
37 #define EXPORT __attribute__ ((visibility ("default")))
38 
39 class ThumbnailRequest;
40 class ThumbnailManager;
41 using RequestSharedPtr = std::shared_ptr<ThumbnailRequest>;
42 using PixelMapPtr = std::unique_ptr<PixelMap>;
43 
44 enum class ThumbnailStatus : int32_t {
45     THUMB_INITIAL = 0,
46     THUMB_FAST,
47     THUMB_QUALITY,
48     THUMB_REMOVE,
49 };
50 
51 struct RequestPhotoParams {
52     std::string uri;
53     std::string path;
54     Size size;
55     RequestPhotoType type;
56 };
57 
58 class ThumbnailCallback {
59 public:
ThumbnailCallback(napi_env env,napi_ref callback)60     ThumbnailCallback(napi_env env, napi_ref callback) : env_(env), callBackRef_(callback)
61     { }
62     virtual ~ThumbnailCallback() = default;
63     napi_env env_;
64     napi_ref callBackRef_;
65 };
66 
67 class ThumnailUv {
68 public:
ThumnailUv(const RequestSharedPtr & request,ThumbnailManager * manager)69     ThumnailUv(const RequestSharedPtr &request, ThumbnailManager *manager) : request_(request),
70         manager_(manager) {}
71     RequestSharedPtr request_;
72     ThumbnailManager *manager_;
73 };
74 
75 class ThumbnailRequest {
76 public:
77     explicit ThumbnailRequest(const RequestPhotoParams &params, napi_env env, napi_ref callback);
78     virtual ~ThumbnailRequest();
79     bool UpdateStatus(ThumbnailStatus status);
80     void ReleaseCallbackRef();
81     ThumbnailStatus GetStatus();
82     bool NeedContinue();
83 
GetUri()84     std::string GetUri() const
85     {
86         return uri_;
87     }
88 
GetPath()89     std::string GetPath() const
90     {
91         return path_;
92     }
93 
GetRequestSize()94     Size GetRequestSize() const
95     {
96         return requestSize_;
97     }
98 
GetPixelMap()99     PixelMapPtr GetPixelMap()
100     {
101         return std::move(pixelMap);
102     }
103 
SetPixelMap(PixelMapPtr ptr)104     void SetPixelMap(PixelMapPtr ptr)
105     {
106         pixelMap = std::move(ptr);
107     }
108 
GetFastPixelMap()109     PixelMapPtr GetFastPixelMap()
110     {
111         return std::move(fastPixelMap);
112     }
113 
SetFastPixelMap(PixelMapPtr ptr)114     void SetFastPixelMap(PixelMapPtr ptr)
115     {
116         fastPixelMap = std::move(ptr);
117     }
118 
SetUUID(const std::string & uuid)119     void SetUUID(const std::string &uuid)
120     {
121         uuid_ = uuid;
122     }
123 
GetUUID()124     std::string GetUUID() const
125     {
126         return uuid_;
127     }
128 
SetFd(int32_t fd)129     void SetFd(int32_t fd)
130     {
131         fd_ = UniqueFd(fd);
132     }
133 
GetFd()134     const UniqueFd &GetFd() const
135     {
136         return fd_;
137     }
138 
139     ThumbnailCallback callback_;
140     RequestPhotoType requestPhotoType;
141     int32_t error = 0;
142 private:
143     std::string uri_;
144     std::string path_;
145     Size requestSize_;
146     ThumbnailStatus status_ = ThumbnailStatus::THUMB_INITIAL;
147     std::mutex mutex_;
148     std::string uuid_;
149     UniqueFd fd_;
150 
151     PixelMapPtr fastPixelMap;
152     PixelMapPtr pixelMap;
153 };
154 
155 class MMapFdPtr {
156 public:
157     explicit MMapFdPtr(int32_t fd, bool isNeedRelease);
158     ~MMapFdPtr();
159     void* GetFdPtr();
160     off_t GetFdSize();
161     bool IsValid();
162 private:
163     void* fdPtr_ = nullptr;
164     off_t size_ = 0;
165     bool isValid_ = false;
166     bool isNeedRelease_ = false;
167 };
168 
169 constexpr int THREAD_NUM = 5;
170 class ThumbnailManager : NoCopyable {
171 public:
172     virtual ~ThumbnailManager();
173     static std::shared_ptr<ThumbnailManager> GetInstance();
174 
175     void Init();
176     std::string AddPhotoRequest(const RequestPhotoParams &params, napi_env env, napi_ref callback);
177     void RemovePhotoRequest(const std::string &requestId);
178     EXPORT static std::unique_ptr<PixelMap> QueryThumbnail(const std::string &uri, const Size &size,
179         const std::string &path);
180     void DeleteRequestIdFromMap(const std::string &requestId);
181     void AddQualityPhotoRequest(const RequestSharedPtr &request);
182 private:
183     ThumbnailManager() = default;
184     void DealWithFastRequest(const RequestSharedPtr &request);
185     void DealWithQualityRequest(const RequestSharedPtr &request);
186 
187     void ImageWorker(int num);
188     void AddFastPhotoRequest(const RequestSharedPtr &request);
189     void NotifyImage(const RequestSharedPtr &request);
190     bool RequestFastImage(const RequestSharedPtr &request);
191 
192     SafeMap<std::string, RequestSharedPtr> thumbRequest_;
193     SafeQueue<RequestSharedPtr> fastQueue_;
194     SafeQueue<RequestSharedPtr> qualityQueue_;
195 
196     std::mutex queueLock_;
197     std::condition_variable queueCv_;
198     std::vector<std::thread> threads_;
199 
200     static std::shared_ptr<ThumbnailManager> instance_;
201     static std::mutex mutex_;
202     static bool init_;
203     std::atomic<bool> isThreadRunning_;
204 };
205 } // Media
206 } // OHOS
207 
208 #endif // INTERFACES_KITS_JS_MEDIALIBRARY_INCLUDE_THUMBNAIL_MANAGER_H
209 
210