1 /*
2  * Copyright (C) 2024 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 struct AssetHandler {
44     std::string photoId;
45     std::string requestId;
46     std::string requestUri;
47     MediaAssetDataHandlerPtr dataHandler;
48     napi_threadsafe_function threadSafeFunc;
49     MultiStagesCapturePhotoStatus photoQuality = MultiStagesCapturePhotoStatus::HIGH_QUALITY_STATUS;
50     bool needsExtraInfo = false;
51 
AssetHandlerAssetHandler52     AssetHandler(const std::string &photoId, const std::string &requestId, const std::string &uri,
53         const MediaAssetDataHandlerPtr &handler, napi_threadsafe_function func)
54         : photoId(photoId), requestId(requestId), requestUri(uri), dataHandler(handler), threadSafeFunc(func) {}
55 };
56 
57 struct MediaAssetManagerAsyncContext : NapiError {
58     napi_async_work work;
59     napi_deferred deferred;
60     napi_ref callbackRef;
61 
62     size_t argc = ARGS_FIVE;
63     napi_value argv[ARGS_FIVE] = {nullptr};
64     int fileId = -1; // default value of request file id
65     std::string photoUri;
66     std::string photoId;
67     std::string displayName;
68     std::string photoPath;
69     std::string requestId;
70     napi_value requestIdNapiValue;
71     napi_value dataHandler;
72     napi_ref dataHandlerRef;
73     std::string destUri;
74     DeliveryMode deliveryMode;
75     SourceMode sourceMode;
76     ReturnDataType returnDataType;
77     bool hasReadPermission;
78     bool needsExtraInfo;
79     MultiStagesCapturePhotoStatus photoQuality = MultiStagesCapturePhotoStatus::HIGH_QUALITY_STATUS;
80     napi_ref dataHandlerRef2;
81     napi_threadsafe_function onDataPreparedPtr;
82     napi_threadsafe_function onDataPreparedPtr2;
83     PhotoSubType subType;
84     bool hasProcessPhoto;
85     AssetHandler *assetHandler = nullptr;
86 };
87 
88 class MultiStagesTaskObserver : public DataShare::DataShareObserver {
89 public:
MultiStagesTaskObserver(int fileId)90     MultiStagesTaskObserver(int fileId)
91         : fileId_(fileId) {};
92     void OnChange(const ChangeInfo &changelnfo) override;
93 private:
94     int fileId_;
95 };
96 
97 class MediaAssetManagerNapi {
98 public:
99     MediaAssetManagerNapi() = default;
100     ~MediaAssetManagerNapi() = default;
101     EXPORT static napi_value Init(napi_env env, napi_value exports);
102     static MultiStagesCapturePhotoStatus QueryPhotoStatus(int fileId, const string& photoUri,
103         std::string &photoId, bool hasReadPermission);
104     static void NotifyMediaDataPrepared(AssetHandler *assetHandler);
105     static void DeleteInProcessMapRecord(const std::string &requestUri);
106     static void NotifyDataPreparedWithoutRegister(napi_env env, MediaAssetManagerAsyncContext *asyncContext);
107     static void OnDataPrepared(napi_env env, napi_value cb, void *context, void *data);
108     static void RegisterTaskObserver(napi_env env, MediaAssetManagerAsyncContext *asyncContext);
109     static void GetByteArrayNapiObject(const std::string &requestUri, napi_value &arrayBuffer, bool isSource,
110         napi_env env);
111     static void GetImageSourceNapiObject(const std::string &fileUri, napi_value &imageSourceNapiObj, bool isSource,
112         napi_env env);
113     static void GetPictureNapiObject(const std::string &fileUri, napi_value &imageSourceNapiObj, bool isSource,
114         napi_env env, bool& isPicture);
115     static void WriteDataToDestPath(std::string requestUri, std::string destUri, napi_value& resultNapiValue,
116         bool isSource, napi_env env);
117 
118 private:
119     static napi_value Constructor(napi_env env, napi_callback_info info);
120     static void Destructor(napi_env env, void *nativeObject, void *finalizeHint);
121     static bool InitUserFileClient(napi_env env, napi_callback_info info);
122     static napi_status ParseRequestMediaArgs(napi_env env, napi_callback_info info,
123         unique_ptr<MediaAssetManagerAsyncContext> &asyncContext);
124     static napi_status ParseEfficentRequestMediaArgs(napi_env env, napi_callback_info info,
125         unique_ptr<MediaAssetManagerAsyncContext> &asyncContext);
126     static napi_value JSRequestImage(napi_env env, napi_callback_info info);
127     static napi_value JSRequestEfficientIImage(napi_env env, napi_callback_info info);
128     static napi_value JSRequestImageData(napi_env env, napi_callback_info info);
129     static napi_value JSRequestMovingPhoto(napi_env env, napi_callback_info info);
130     static napi_value JSCancelRequest(napi_env env, napi_callback_info info);
131     static napi_value JSRequestVideoFile(napi_env env, napi_callback_info info);
132     static napi_value JSLoadMovingPhoto(napi_env env, napi_callback_info info);
133     static void ProcessImage(const int fileId, const int deliveryMode);
134     static void CancelProcessImage(const std::string &photoId);
135     static void AddImage(const int fileId, DeliveryMode deliveryMode);
136     static void OnHandleRequestImage(napi_env env, MediaAssetManagerAsyncContext *asyncContext);
137     static void OnHandleRequestVideo(napi_env env, MediaAssetManagerAsyncContext *asyncContext);
138     static void SendFile(napi_env env, int srcFd, int destFd, napi_value &result, off_t fileSize);
139     static int32_t GetFdFromSandBoxUri(const std::string &sandBoxUri);
140 
141     static napi_status CreateDataHandlerRef(napi_env env, const unique_ptr<MediaAssetManagerAsyncContext> &context,
142         napi_ref &dataHandlerRef);
143     static napi_status CreateOnDataPreparedThreadSafeFunc(napi_env env,
144         const unique_ptr<MediaAssetManagerAsyncContext> &context, napi_threadsafe_function &threadSafeFunc);
145     static void JSRequestExecute(napi_env env, void *data);
146     static void JSRequestVideoFileExecute(napi_env env, void *data);
147     static void JSRequestComplete(napi_env env, napi_status, void *data);
148     static void JSCancelRequestExecute(napi_env env, void *data);
149     static void JSCancelRequestComplete(napi_env env, napi_status, void *data);
150 public:
151     std::mutex sMediaAssetMutex_;
152 };
153 } // Media
154 } // OHOS
155 #endif // INTERFACES_KITS_JS_MEDIALIBRARY_INCLUDE_MEDIA_ASSET_MANAGER_NAPI_H
156