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_MEDIA_ASSET_MANAGER_NAPI_H
17 #define INTERFACES_KITS_JS_MEDIALIBRARY_INCLUDE_MEDIA_ASSET_MANAGER_NAPI_H
18 
19 #include <mutex>
20 #include <vector>
21 #include <map>
22 
23 #include "data_ability_helper.h"
24 #include "data_ability_observer_stub.h"
25 #include "data_ability_predicates.h"
26 #include "media_asset_data_handler.h"
27 #include "media_file_utils.h"
28 #include "media_library_napi.h"
29 #include "napi_base_context.h"
30 #include "napi_error.h"
31 #include "napi/native_api.h"
32 #include "napi/native_node_api.h"
33 
34 namespace OHOS {
35 namespace Media {
36 using MediaAssetDataHandlerPtr = std::shared_ptr<NapiMediaAssetDataHandler>;
37 enum class MultiStagesCapturePhotoStatus {
38     QUERY_INNER_FAIL = 0,
39     HIGH_QUALITY_STATUS,
40     LOW_QUALITY_STATUS,
41 };
42 
43 enum ProgressReturnInfoType : int32_t {
44     INFO_TYPE_TRANSCODER_COMPLETED = 0,
45     INFO_TYPE_PROGRESS_UPDATE,
46     INFO_TYPE_ERROR,
47 };
48 
49 struct AssetHandler {
50     std::string photoId;
51     std::string requestId;
52     std::string requestUri;
53     MediaAssetDataHandlerPtr dataHandler;
54     napi_threadsafe_function threadSafeFunc;
55     MultiStagesCapturePhotoStatus photoQuality = MultiStagesCapturePhotoStatus::HIGH_QUALITY_STATUS;
56     bool needsExtraInfo = false;
57 
AssetHandlerOHOS::Media::AssetHandler58     AssetHandler(const std::string &photoId, const std::string &requestId, const std::string &uri,
59         const MediaAssetDataHandlerPtr &handler, napi_threadsafe_function func)
60         : photoId(photoId), requestId(requestId), requestUri(uri), dataHandler(handler), threadSafeFunc(func) {}
61 };
62 
63 struct RetProgressValue {
64     int32_t progress;
65     int32_t type;
66     std::string errorMsg;
67 };
68 
69 struct ProgressHandler {
70     napi_env env;
71     napi_threadsafe_function progressFunc;
72     std::string requestId;
73     RetProgressValue retProgressValue;
74     napi_ref progressRef;
ProgressHandlerOHOS::Media::ProgressHandler75     ProgressHandler(napi_env env, napi_threadsafe_function func, const std::string &requestId,
76         RetProgressValue &retProgressValue, napi_ref progressRef) : env(env), progressFunc(func),
77         requestId(requestId), retProgressValue(retProgressValue), progressRef(progressRef) {}
78 };
79 
80 struct MediaAssetManagerAsyncContext : NapiError {
81     napi_async_work work;
82     napi_deferred deferred;
83     napi_ref callbackRef;
84 
85     size_t argc = ARGS_FIVE;
86     napi_value argv[ARGS_FIVE] = {nullptr};
87     int fileId = -1; // default value of request file id
88     std::string photoUri;
89     std::string photoId;
90     std::string displayName;
91     std::string photoPath;
92     std::string requestId;
93     napi_value requestIdNapiValue;
94     napi_value dataHandler;
95     napi_ref dataHandlerRef;
96     std::string destUri;
97     DeliveryMode deliveryMode;
98     SourceMode sourceMode;
99     ReturnDataType returnDataType;
100     bool hasReadPermission;
101     bool needsExtraInfo;
102     MultiStagesCapturePhotoStatus photoQuality = MultiStagesCapturePhotoStatus::HIGH_QUALITY_STATUS;
103     napi_ref dataHandlerRef2;
104     napi_threadsafe_function onDataPreparedPtr;
105     napi_threadsafe_function onDataPreparedPtr2;
106     napi_threadsafe_function onProgressPtr;
107     napi_ref progressHandlerRef;
108     PhotoSubType subType;
109     bool hasProcessPhoto;
110     AssetHandler *assetHandler = nullptr;
111     CompatibleMode compatibleMode;
112     napi_value mediaAssetProgressHandler;
113     ProgressHandler *progressHandler = nullptr;
114 };
115 
116 class MultiStagesTaskObserver : public DataShare::DataShareObserver {
117 public:
MultiStagesTaskObserver(int fileId)118     MultiStagesTaskObserver(int fileId)
119         : fileId_(fileId) {};
120     void OnChange(const ChangeInfo &changelnfo) override;
121 private:
122     int fileId_;
123 };
124 
125 struct WriteData {
126     std::string requestUri;
127     std::string destUri;
128     bool isSource;
129     napi_env env;
130     CompatibleMode compatibleMode;
131 };
132 
133 class MediaAssetManagerNapi {
134 public:
135     MediaAssetManagerNapi() = default;
136     ~MediaAssetManagerNapi() = default;
137     EXPORT static napi_value Init(napi_env env, napi_value exports);
138     static MultiStagesCapturePhotoStatus QueryPhotoStatus(int fileId, const string& photoUri,
139         std::string &photoId, bool hasReadPermission);
140     static void NotifyMediaDataPrepared(AssetHandler *assetHandler);
141     static void NotifyOnProgress(int32_t type, int32_t progress, std::string requestId);
142     static void NotifyDataPreparedWithoutRegister(napi_env env, MediaAssetManagerAsyncContext *asyncContext);
143     static void OnDataPrepared(napi_env env, napi_value cb, void *context, void *data);
144     static void OnProgress(napi_env env, napi_value cb, void *context, void *data);
145     static void RegisterTaskObserver(napi_env env, MediaAssetManagerAsyncContext *asyncContext);
146     static void GetByteArrayNapiObject(const std::string &requestUri, napi_value &arrayBuffer, bool isSource,
147         napi_env env);
148     static void GetImageSourceNapiObject(const std::string &fileUri, napi_value &imageSourceNapiObj, bool isSource,
149         napi_env env);
150     static void GetPictureNapiObject(const std::string &fileUri, napi_value &imageSourceNapiObj, bool isSource,
151         napi_env env, bool& isPicture);
152     static void WriteDataToDestPath(WriteData &writeData, napi_value &resultNapiValue, std::string requestId);
153     void RegisterCallback(std::function<void(int, int)> cb);
154 
155 private:
156     static napi_value Constructor(napi_env env, napi_callback_info info);
157     static void Destructor(napi_env env, void *nativeObject, void *finalizeHint);
158     static bool InitUserFileClient(napi_env env, napi_callback_info info);
159     static napi_status ParseRequestMediaArgs(napi_env env, napi_callback_info info,
160         unique_ptr<MediaAssetManagerAsyncContext> &asyncContext);
161     static napi_status ParseEfficentRequestMediaArgs(napi_env env, napi_callback_info info,
162         unique_ptr<MediaAssetManagerAsyncContext> &asyncContext);
163     static napi_value JSRequestImage(napi_env env, napi_callback_info info);
164     static napi_value JSRequestEfficientIImage(napi_env env, napi_callback_info info);
165     static napi_value JSRequestImageData(napi_env env, napi_callback_info info);
166     static napi_value JSRequestMovingPhoto(napi_env env, napi_callback_info info);
167     static napi_value JSRequestVideoFile(napi_env env, napi_callback_info info);
168     static napi_value JSCancelRequest(napi_env env, napi_callback_info info);
169     static napi_value JSLoadMovingPhoto(napi_env env, napi_callback_info info);
170     static void ProcessImage(const int fileId, const int deliveryMode);
171     static void CancelProcessImage(const std::string &photoId);
172     static void AddImage(const int fileId, DeliveryMode deliveryMode);
173     static void OnHandleRequestImage(napi_env env, MediaAssetManagerAsyncContext *asyncContext);
174     static void OnHandleRequestVideo(napi_env env, MediaAssetManagerAsyncContext *asyncContext);
175     static void OnHandleProgress(napi_env env, MediaAssetManagerAsyncContext *asyncContext);
176     static void SendFile(napi_env env, int srcFd, int destFd, napi_value &result, off_t fileSize);
177     static int32_t GetFdFromSandBoxUri(const std::string &sandBoxUri);
178 
179     static napi_status CreateDataHandlerRef(napi_env env, const unique_ptr<MediaAssetManagerAsyncContext> &context,
180         napi_ref &dataHandlerRef);
181     static napi_status CreateProgressHandlerRef(napi_env env, const unique_ptr<MediaAssetManagerAsyncContext> &context,
182         napi_ref &dataHandlerRef);
183     static napi_status CreateOnDataPreparedThreadSafeFunc(napi_env env,
184         const unique_ptr<MediaAssetManagerAsyncContext> &context, napi_threadsafe_function &threadSafeFunc);
185     static napi_status CreateOnProgressThreadSafeFunc(napi_env env,
186          unique_ptr<MediaAssetManagerAsyncContext> &context, napi_threadsafe_function &progressFunc);
187     static void JSRequestExecute(napi_env env, void *data);
188     static void JSRequestVideoFileExecute(napi_env env, void *data);
189     static void JSRequestComplete(napi_env env, napi_status, void *data);
190     static void JSCancelRequestExecute(napi_env env, void *data);
191     static void JSCancelRequestComplete(napi_env env, napi_status, void *data);
192     static bool CreateOnProgressHandlerInfo(napi_env env, unique_ptr<MediaAssetManagerAsyncContext> &asyncContext);
193 public:
194     std::mutex sMediaAssetMutex_;
195     static inline SafeMap<std::string, ProgressHandler*> progressHandlerMap_;
196 };
197 } // Media
198 } // OHOS
199 #endif // INTERFACES_KITS_JS_MEDIALIBRARY_INCLUDE_MEDIA_ASSET_MANAGER_NAPI_H
200