1 /*
2 * Copyright (C) 2025 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 #define MLOG_TAG "AlbumOrderNapi"
16
17 #include "album_order_napi.h"
18 #include <nlohmann/json.hpp>
19
20 #include "fetch_file_result_napi.h"
21 #include "media_file_utils.h"
22 #include "medialibrary_client_errno.h"
23 #include "medialibrary_napi_log.h"
24 #include "medialibrary_napi_utils_ext.h"
25 #include "medialibrary_tracer.h"
26 #include "result_set_utils.h"
27 #include "userfile_client.h"
28 #include "album_operation_uri.h"
29
30 using namespace std;
31 using namespace OHOS::DataShare;
32
33 namespace OHOS::Media {
34 thread_local AlbumOrder *AlbumOrderNapi::pOrderData_ = nullptr;
35 thread_local napi_ref AlbumOrderNapi::photoAccessConstructor_ = nullptr;
36 static const string PHOTOACCESS_ALBUM_ORDER_CLASS = "PhotoAccessAlbumOrder";
37 std::mutex AlbumOrderNapi::mutex_;
38
39 using CompleteCallback = napi_async_complete_callback;
40
AlbumOrderNapi()41 AlbumOrderNapi::AlbumOrderNapi() : env_(nullptr) {}
42
43 AlbumOrderNapi::~AlbumOrderNapi() = default;
44
PhotoAccessInit(napi_env env,napi_value exports)45 napi_value AlbumOrderNapi::PhotoAccessInit(napi_env env, napi_value exports)
46 {
47 NapiClassInfo info = {
48 .name = PHOTOACCESS_ALBUM_ORDER_CLASS,
49 .ref = &photoAccessConstructor_,
50 .constructor = AlbumOrderNapiConstructor,
51 .props = {
52 DECLARE_NAPI_GETTER_SETTER("albumId", JSGetAlbumId, JSSetAlbumId),
53 DECLARE_NAPI_GETTER_SETTER("albumOrder", JSGetAlbumOrder, JSSetAlbumOrder),
54 DECLARE_NAPI_GETTER_SETTER("orderSection", JSGetOrderSection, JSSetOrderSection),
55 DECLARE_NAPI_GETTER_SETTER("orderType", JSGetOrderType, JSSetOrderType),
56 DECLARE_NAPI_GETTER_SETTER("orderStatus", JSGetOrderStatus, JSSetOrderStatus),
57 }
58 };
59
60 MediaLibraryNapiUtils::NapiDefineClass(env, exports, info);
61 return exports;
62 }
63
CreateAlbumOrderNapi(napi_env env,unique_ptr<AlbumOrder> & orderData)64 napi_value AlbumOrderNapi::CreateAlbumOrderNapi(napi_env env, unique_ptr<AlbumOrder> &orderData)
65 {
66 if (orderData == nullptr) {
67 NAPI_ERR_LOG("Unsupported album order data");
68 return nullptr;
69 }
70 if (photoAccessConstructor_ == nullptr) {
71 napi_value exports = nullptr;
72 napi_create_object(env, &exports);
73 AlbumOrderNapi::PhotoAccessInit(env, exports);
74 }
75
76 napi_value constructor;
77 napi_ref constructorRef = photoAccessConstructor_;
78 CHECK_ARGS(env, napi_get_reference_value(env, constructorRef, &constructor), JS_E_INNER_FAIL);
79
80 napi_value result = nullptr;
81 pOrderData_ = orderData.release();
82 CHECK_ARGS(env, napi_new_instance(env, constructor, 0, nullptr, &result), JS_E_INNER_FAIL);
83 pOrderData_ = nullptr;
84 return result;
85 }
86
GetAlbumId() const87 int32_t AlbumOrderNapi::GetAlbumId() const
88 {
89 return albumOrderPtr->GetAlbumId();
90 }
91
GetAlbumOrder() const92 int32_t AlbumOrderNapi::GetAlbumOrder() const
93 {
94 return albumOrderPtr->GetAlbumOrder();
95 }
96
GetOrderSection() const97 int32_t AlbumOrderNapi::GetOrderSection() const
98 {
99 return albumOrderPtr->GetOrderSection();
100 }
101
GetOrderType() const102 int32_t AlbumOrderNapi::GetOrderType() const
103 {
104 return albumOrderPtr->GetOrderType();
105 }
106
GetOrderStatus() const107 int32_t AlbumOrderNapi::GetOrderStatus() const
108 {
109 return albumOrderPtr->GetOrderStatus();
110 }
111
GetAlbumOrderInstance() const112 shared_ptr<AlbumOrder> AlbumOrderNapi::GetAlbumOrderInstance() const
113 {
114 return albumOrderPtr;
115 }
116
SetAlbumOrderNapiProperties()117 void AlbumOrderNapi::SetAlbumOrderNapiProperties()
118 {
119 albumOrderPtr = shared_ptr<AlbumOrder>(pOrderData_);
120 }
121
122 // Constructor callback
AlbumOrderNapiConstructor(napi_env env,napi_callback_info info)123 napi_value AlbumOrderNapi::AlbumOrderNapiConstructor(napi_env env, napi_callback_info info)
124 {
125 napi_value result = nullptr;
126 CHECK_ARGS(env, napi_get_undefined(env, &result), JS_E_INNER_FAIL);
127
128 napi_value thisVar = nullptr;
129 CHECK_ARGS(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr), JS_E_INNER_FAIL);
130 if (thisVar == nullptr) {
131 NapiError::ThrowError(env, JS_E_PARAM_INVALID, "Failed to get cb info");
132 return result;
133 }
134
135 unique_ptr<AlbumOrderNapi> obj = make_unique<AlbumOrderNapi>();
136 obj->env_ = env;
137 if (pOrderData_ != nullptr) {
138 obj->SetAlbumOrderNapiProperties();
139 }
140 CHECK_ARGS(env, napi_wrap(env, thisVar, reinterpret_cast<void *>(obj.get()),
141 AlbumOrderNapi::AlbumOrderNapiDestructor, nullptr, nullptr), JS_E_INNER_FAIL);
142 obj.release();
143 return thisVar;
144 }
145
AlbumOrderNapiDestructor(napi_env env,void * nativeObject,void * finalizeHint)146 void AlbumOrderNapi::AlbumOrderNapiDestructor(napi_env env, void *nativeObject, void *finalizeHint)
147 {
148 auto *order = reinterpret_cast<AlbumOrderNapi*>(nativeObject);
149 lock_guard<mutex> lockGuard(mutex_);
150 if (order != nullptr) {
151 delete order;
152 order = nullptr;
153 }
154 }
155
UnwrapAlbumOrderObject(napi_env env,napi_callback_info info,AlbumOrderNapi ** obj)156 napi_value UnwrapAlbumOrderObject(napi_env env, napi_callback_info info, AlbumOrderNapi** obj)
157 {
158 napi_value result = nullptr;
159 CHECK_ARGS(env, napi_get_undefined(env, &result), JS_E_INNER_FAIL);
160
161 napi_value thisVar = nullptr;
162 CHECK_ARGS(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr), JS_E_INNER_FAIL);
163 if (thisVar == nullptr) {
164 NapiError::ThrowError(env, JS_E_PARAM_INVALID, "Failed to get cb info");
165 return result;
166 }
167
168 CHECK_ARGS(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(obj)), JS_E_INNER_FAIL);
169 if (obj == nullptr) {
170 NapiError::ThrowError(env, JS_E_PARAM_INVALID, "Failed to get album order napi object");
171 return result;
172 }
173
174 CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_E_INNER_FAIL);
175 return result;
176 }
177
GetInt32Arg(napi_env env,napi_callback_info info,AlbumOrderNapi ** obj,int32_t & value)178 napi_value GetInt32Arg(napi_env env, napi_callback_info info, AlbumOrderNapi** obj, int32_t &value)
179 {
180 size_t argc = ARGS_ONE;
181 napi_value argv[ARGS_ONE];
182 napi_value thisVar = nullptr;
183 CHECK_ARGS(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr), JS_E_INNER_FAIL);
184 CHECK_COND(env, argc == ARGS_ONE, JS_E_PARAM_INVALID);
185
186 napi_value result = nullptr;
187 CHECK_ARGS(env, napi_get_undefined(env, &result), JS_E_INNER_FAIL);
188 napi_valuetype valueType = napi_undefined;
189 if ((thisVar == nullptr) || (napi_typeof(env, argv[PARAM0], &valueType) != napi_ok) || (valueType != napi_number)) {
190 NapiError::ThrowError(env, JS_E_PARAM_INVALID, "Invalid arguments type!");
191 return result;
192 }
193
194 CHECK_ARGS(env, napi_get_value_int32(env, argv[PARAM0], &value), JS_E_INNER_FAIL);
195 CHECK_ARGS(env, napi_unwrap(env, thisVar, reinterpret_cast<void **>(obj)), JS_E_INNER_FAIL);
196 if (obj == nullptr) {
197 NapiError::ThrowError(env, JS_E_PARAM_INVALID, "Failed to get album order napi object");
198 return result;
199 }
200
201 CHECK_ARGS(env, napi_get_boolean(env, true, &result), JS_E_INNER_FAIL);
202 return result;
203 }
204
JSGetAlbumId(napi_env env,napi_callback_info info)205 napi_value AlbumOrderNapi::JSGetAlbumId(napi_env env, napi_callback_info info)
206 {
207 AlbumOrderNapi *obj = nullptr;
208 CHECK_NULLPTR_RET(UnwrapAlbumOrderObject(env, info, &obj));
209
210 napi_value jsResult = nullptr;
211 CHECK_ARGS(env, napi_create_int32(env, obj->GetAlbumId(), &jsResult), JS_E_INNER_FAIL);
212 return jsResult;
213 }
214
JSSetAlbumId(napi_env env,napi_callback_info info)215 napi_value AlbumOrderNapi::JSSetAlbumId(napi_env env, napi_callback_info info)
216 {
217 AlbumOrderNapi *obj = nullptr;
218 int32_t albumId;
219 CHECK_COND(env, GetInt32Arg(env, info, &obj, albumId), JS_E_PARAM_INVALID);
220 obj->albumOrderPtr->SetAlbumId(albumId);
221
222 napi_value result = nullptr;
223 CHECK_ARGS(env, napi_get_undefined(env, &result), JS_E_INNER_FAIL);
224 return result;
225 }
226
JSGetAlbumOrder(napi_env env,napi_callback_info info)227 napi_value AlbumOrderNapi::JSGetAlbumOrder(napi_env env, napi_callback_info info)
228 {
229 AlbumOrderNapi *obj = nullptr;
230 CHECK_NULLPTR_RET(UnwrapAlbumOrderObject(env, info, &obj));
231
232 napi_value jsResult = nullptr;
233 CHECK_ARGS(env, napi_create_int32(env, obj->GetAlbumOrder(), &jsResult), JS_E_INNER_FAIL);
234 return jsResult;
235 }
236
JSSetAlbumOrder(napi_env env,napi_callback_info info)237 napi_value AlbumOrderNapi::JSSetAlbumOrder(napi_env env, napi_callback_info info)
238 {
239 AlbumOrderNapi *obj = nullptr;
240 int32_t albumOrder;
241 CHECK_COND(env, GetInt32Arg(env, info, &obj, albumOrder), JS_E_PARAM_INVALID);
242 obj->albumOrderPtr->SetAlbumOrder(albumOrder);
243
244 napi_value result = nullptr;
245 CHECK_ARGS(env, napi_get_undefined(env, &result), JS_E_INNER_FAIL);
246 return result;
247 }
248
JSGetOrderSection(napi_env env,napi_callback_info info)249 napi_value AlbumOrderNapi::JSGetOrderSection(napi_env env, napi_callback_info info)
250 {
251 AlbumOrderNapi *obj = nullptr;
252 CHECK_NULLPTR_RET(UnwrapAlbumOrderObject(env, info, &obj));
253
254 napi_value jsResult = nullptr;
255 CHECK_ARGS(env, napi_create_int32(env, obj->GetOrderSection(), &jsResult), JS_E_INNER_FAIL);
256 return jsResult;
257 }
258
JSSetOrderSection(napi_env env,napi_callback_info info)259 napi_value AlbumOrderNapi::JSSetOrderSection(napi_env env, napi_callback_info info)
260 {
261 AlbumOrderNapi *obj = nullptr;
262 int32_t orderSection;
263 CHECK_COND(env, GetInt32Arg(env, info, &obj, orderSection), JS_E_PARAM_INVALID);
264 obj->albumOrderPtr->SetOrderSection(orderSection);
265
266 napi_value result = nullptr;
267 CHECK_ARGS(env, napi_get_undefined(env, &result), JS_E_INNER_FAIL);
268 return result;
269 }
270
JSGetOrderType(napi_env env,napi_callback_info info)271 napi_value AlbumOrderNapi::JSGetOrderType(napi_env env, napi_callback_info info)
272 {
273 AlbumOrderNapi *obj = nullptr;
274 CHECK_NULLPTR_RET(UnwrapAlbumOrderObject(env, info, &obj));
275
276 napi_value jsResult = nullptr;
277 CHECK_ARGS(env, napi_create_int32(env, obj->GetOrderType(), &jsResult), JS_E_INNER_FAIL);
278 return jsResult;
279 }
280
JSSetOrderType(napi_env env,napi_callback_info info)281 napi_value AlbumOrderNapi::JSSetOrderType(napi_env env, napi_callback_info info)
282 {
283 AlbumOrderNapi *obj = nullptr;
284 int32_t orderType;
285 CHECK_COND(env, GetInt32Arg(env, info, &obj, orderType), JS_E_PARAM_INVALID);
286 obj->albumOrderPtr->SetOrderType(orderType);
287
288 napi_value result = nullptr;
289 CHECK_ARGS(env, napi_get_undefined(env, &result), JS_E_INNER_FAIL);
290 return result;
291 }
292
JSGetOrderStatus(napi_env env,napi_callback_info info)293 napi_value AlbumOrderNapi::JSGetOrderStatus(napi_env env, napi_callback_info info)
294 {
295 AlbumOrderNapi *obj = nullptr;
296 CHECK_NULLPTR_RET(UnwrapAlbumOrderObject(env, info, &obj));
297
298 napi_value jsResult = nullptr;
299 CHECK_ARGS(env, napi_create_int32(env, obj->GetOrderStatus(), &jsResult), JS_E_INNER_FAIL);
300 return jsResult;
301 }
302
JSSetOrderStatus(napi_env env,napi_callback_info info)303 napi_value AlbumOrderNapi::JSSetOrderStatus(napi_env env, napi_callback_info info)
304 {
305 AlbumOrderNapi *obj = nullptr;
306 int32_t orderStatus;
307 CHECK_COND(env, GetInt32Arg(env, info, &obj, orderStatus), JS_E_PARAM_INVALID);
308 obj->albumOrderPtr->SetOrderStatus(orderStatus);
309
310 napi_value result = nullptr;
311 CHECK_ARGS(env, napi_get_undefined(env, &result), JS_E_INNER_FAIL);
312 return result;
313 }
314 } // namespace OHOS::Media