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 #define MLOG_TAG "MediaAssetEditDataNapi"
17 
18 #include "media_asset_edit_data_napi.h"
19 
20 #include "medialibrary_client_errno.h"
21 #include "medialibrary_errno.h"
22 #include "medialibrary_napi_log.h"
23 
24 using namespace std;
25 
26 namespace OHOS::Media {
27 static const string MEDIA_ASSET_EDIT_DATA_CLASS = "MediaAssetEditData";
28 thread_local napi_ref MediaAssetEditDataNapi::constructor_ = nullptr;
29 
30 constexpr int32_t EDIT_DATA_MAX_LENGTH = 5 * 1024 * 1024;
31 constexpr int32_t EDIT_FORMAT_MAX_LENGTH = 256;
32 
Init(napi_env env,napi_value exports)33 napi_value MediaAssetEditDataNapi::Init(napi_env env, napi_value exports)
34 {
35     NapiClassInfo info = { .name = MEDIA_ASSET_EDIT_DATA_CLASS,
36         .ref = &constructor_,
37         .constructor = Constructor,
38         .props = {
39             DECLARE_NAPI_GETTER_SETTER("compatibleFormat", JSGetCompatibleFormat, JSSetCompatibleFormat),
40             DECLARE_NAPI_GETTER_SETTER("formatVersion", JSGetFormatVersion, JSSetFormatVersion),
41             DECLARE_NAPI_GETTER_SETTER("data", JSGetData, JSSetData),
42         } };
43     MediaLibraryNapiUtils::NapiDefineClass(env, exports, info);
44     return exports;
45 }
46 
Constructor(napi_env env,napi_callback_info info)47 napi_value MediaAssetEditDataNapi::Constructor(napi_env env, napi_callback_info info)
48 {
49     if (!MediaLibraryNapiUtils::IsSystemApp()) {
50         NapiError::ThrowError(env, E_CHECK_SYSTEMAPP_FAIL, "The constructor can be called only by system apps");
51         return nullptr;
52     }
53 
54     napi_value newTarget = nullptr;
55     CHECK_ARGS(env, napi_get_new_target(env, info, &newTarget), JS_INNER_FAIL);
56     CHECK_COND_RET(newTarget != nullptr, nullptr, "Failed to check new.target");
57 
58     size_t argc = ARGS_TWO;
59     napi_value argv[ARGS_TWO] = { 0 };
60     napi_value thisVar = nullptr;
61     string compatibleFormat;
62     string formatVersion;
63     CHECK_ARGS(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr), JS_INNER_FAIL);
64     CHECK_COND_WITH_MESSAGE(env, argc == ARGS_TWO, "Number of args is invalid");
65     CHECK_ARGS_THROW_INVALID_PARAM(env,
66         MediaLibraryNapiUtils::GetParamStringWithLength(env, argv[PARAM0], EDIT_FORMAT_MAX_LENGTH, compatibleFormat));
67     CHECK_ARGS_THROW_INVALID_PARAM(env,
68         MediaLibraryNapiUtils::GetParamStringWithLength(env, argv[PARAM1], EDIT_FORMAT_MAX_LENGTH, formatVersion));
69 
70     shared_ptr<MediaAssetEditData> editData = make_shared<MediaAssetEditData>(compatibleFormat, formatVersion);
71     unique_ptr<MediaAssetEditDataNapi> obj = make_unique<MediaAssetEditDataNapi>();
72     CHECK_COND(env, editData != nullptr && obj != nullptr, JS_INNER_FAIL);
73     obj->editData_ = editData;
74     CHECK_ARGS(env,
75         napi_wrap(env, thisVar, reinterpret_cast<void*>(obj.get()),
76             MediaAssetEditDataNapi::Destructor, nullptr, nullptr),
77         JS_INNER_FAIL);
78     obj.release();
79     return thisVar;
80 }
81 
Destructor(napi_env env,void * nativeObject,void * finalizeHint)82 void MediaAssetEditDataNapi::Destructor(napi_env env, void* nativeObject, void* finalizeHint)
83 {
84     auto* assetEditData = reinterpret_cast<MediaAssetEditDataNapi*>(nativeObject);
85     if (assetEditData != nullptr) {
86         delete assetEditData;
87         assetEditData = nullptr;
88     }
89 }
90 
CreateMediaAssetEditData(napi_env env,const string & compatibleFormat,const string & formatVersion,const string & data)91 napi_value MediaAssetEditDataNapi::CreateMediaAssetEditData(napi_env env,
92     const string& compatibleFormat, const string& formatVersion, const string& data)
93 {
94     napi_value constructor = nullptr;
95     napi_value instance = nullptr;
96     napi_value argv[ARGS_TWO];
97     CHECK_ARGS(env, napi_create_string_utf8(env, compatibleFormat.c_str(),
98         NAPI_AUTO_LENGTH, &(argv[PARAM0])), JS_INNER_FAIL);
99     CHECK_ARGS(env, napi_create_string_utf8(env, formatVersion.c_str(),
100         NAPI_AUTO_LENGTH, &(argv[PARAM1])), JS_INNER_FAIL);
101     CHECK_ARGS(env, napi_get_reference_value(env, constructor_, &constructor), JS_INNER_FAIL);
102     CHECK_ARGS(env, napi_new_instance(env, constructor, ARGS_TWO, argv, &instance), JS_INNER_FAIL);
103     CHECK_COND(env, instance != nullptr, JS_INNER_FAIL);
104 
105     MediaAssetEditDataNapi* assetEditData = nullptr;
106     CHECK_ARGS(env, napi_unwrap(env, instance, reinterpret_cast<void**>(&assetEditData)), JS_INNER_FAIL);
107     CHECK_COND(env, assetEditData != nullptr, JS_INNER_FAIL);
108     assetEditData->SetData(data);
109     return instance;
110 }
111 
GetMediaAssetEditData() const112 shared_ptr<MediaAssetEditData> MediaAssetEditDataNapi::GetMediaAssetEditData() const
113 {
114     return editData_;
115 }
116 
GetCompatibleFormat() const117 string MediaAssetEditDataNapi::GetCompatibleFormat() const
118 {
119     return editData_->GetCompatibleFormat();
120 }
121 
SetCompatibleFormat(const string & compatibleFormat)122 void MediaAssetEditDataNapi::SetCompatibleFormat(const string& compatibleFormat)
123 {
124     editData_->SetCompatibleFormat(compatibleFormat);
125 }
126 
GetFormatVersion() const127 string MediaAssetEditDataNapi::GetFormatVersion() const
128 {
129     return editData_->GetFormatVersion();
130 }
131 
SetFormatVersion(const string & formatVersion)132 void MediaAssetEditDataNapi::SetFormatVersion(const string& formatVersion)
133 {
134     editData_->SetFormatVersion(formatVersion);
135 }
136 
GetData() const137 string MediaAssetEditDataNapi::GetData() const
138 {
139     return editData_->GetData();
140 }
141 
SetData(const string & data)142 void MediaAssetEditDataNapi::SetData(const string& data)
143 {
144     editData_->SetData(data);
145 }
146 
JSGetCompatibleFormat(napi_env env,napi_callback_info info)147 napi_value MediaAssetEditDataNapi::JSGetCompatibleFormat(napi_env env, napi_callback_info info)
148 {
149     napi_status status;
150     napi_value thisVar = nullptr;
151     napi_value result = nullptr;
152     MediaAssetEditDataNapi* obj = nullptr;
153 
154     napi_get_undefined(env, &result);
155     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
156     if (status != napi_ok || thisVar == nullptr) {
157         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
158         return result;
159     }
160 
161     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&obj));
162     if (status == napi_ok && obj != nullptr) {
163         string compatibleFormat = obj->GetCompatibleFormat();
164         napi_create_string_utf8(env, compatibleFormat.c_str(), NAPI_AUTO_LENGTH, &result);
165     } else {
166         NAPI_ERR_LOG("Failed to get compatibleFormat");
167     }
168     return result;
169 }
170 
JSGetFormatVersion(napi_env env,napi_callback_info info)171 napi_value MediaAssetEditDataNapi::JSGetFormatVersion(napi_env env, napi_callback_info info)
172 {
173     napi_status status;
174     napi_value thisVar = nullptr;
175     napi_value result = nullptr;
176     MediaAssetEditDataNapi* obj = nullptr;
177 
178     napi_get_undefined(env, &result);
179     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
180     if (status != napi_ok || thisVar == nullptr) {
181         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
182         return result;
183     }
184 
185     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&obj));
186     if (status == napi_ok && obj != nullptr) {
187         string formatVersion = obj->GetFormatVersion();
188         napi_create_string_utf8(env, formatVersion.c_str(), NAPI_AUTO_LENGTH, &result);
189     } else {
190         NAPI_ERR_LOG("Failed to get formatVersion");
191     }
192     return result;
193 }
194 
JSGetData(napi_env env,napi_callback_info info)195 napi_value MediaAssetEditDataNapi::JSGetData(napi_env env, napi_callback_info info)
196 {
197     napi_status status;
198     napi_value thisVar = nullptr;
199     napi_value result = nullptr;
200     MediaAssetEditDataNapi* obj = nullptr;
201 
202     napi_get_undefined(env, &result);
203     GET_JS_OBJ_WITH_ZERO_ARGS(env, info, status, thisVar);
204     if (status != napi_ok || thisVar == nullptr) {
205         NAPI_ERR_LOG("Invalid arguments! status: %{public}d", status);
206         return result;
207     }
208 
209     status = napi_unwrap(env, thisVar, reinterpret_cast<void**>(&obj));
210     if (status == napi_ok && obj != nullptr) {
211         string data = obj->GetData();
212         napi_create_string_utf8(env, data.c_str(), NAPI_AUTO_LENGTH, &result);
213     } else {
214         NAPI_ERR_LOG("Failed to get data");
215     }
216     return result;
217 }
218 
GetStringArg(napi_env env,napi_callback_info info,MediaAssetEditDataNapi ** obj,int maxLen,string & arg)219 static napi_value GetStringArg(
220     napi_env env, napi_callback_info info, MediaAssetEditDataNapi** obj, int maxLen, string& arg)
221 {
222     size_t argc = ARGS_ONE;
223     napi_value argv[ARGS_ONE];
224     napi_value thisVar = nullptr;
225     napi_valuetype valueType = napi_undefined;
226     CHECK_ARGS(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr), JS_INNER_FAIL);
227     CHECK_COND(env, argc == ARGS_ONE && thisVar != nullptr, OHOS_INVALID_PARAM_CODE);
228     CHECK_ARGS(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(obj)), JS_INNER_FAIL);
229     CHECK_COND(env, obj != nullptr, OHOS_INVALID_PARAM_CODE);
230     CHECK_COND(env, napi_typeof(env, argv[PARAM0], &valueType) == napi_ok && valueType == napi_string,
231         OHOS_INVALID_PARAM_CODE);
232 
233     size_t res = 0;
234     char buffer[maxLen];
235     CHECK_ARGS(env, napi_get_value_string_utf8(env, argv[PARAM0], buffer, maxLen, &res), JS_INNER_FAIL);
236     arg = string(buffer);
237     RETURN_NAPI_TRUE(env);
238 }
239 
JSSetCompatibleFormat(napi_env env,napi_callback_info info)240 napi_value MediaAssetEditDataNapi::JSSetCompatibleFormat(napi_env env, napi_callback_info info)
241 {
242     MediaAssetEditDataNapi* obj = nullptr;
243     string compatibleFormat;
244     CHECK_NULLPTR_RET(GetStringArg(env, info, &obj, EDIT_FORMAT_MAX_LENGTH, compatibleFormat));
245     obj->SetCompatibleFormat(compatibleFormat);
246     RETURN_NAPI_UNDEFINED(env);
247 }
248 
JSSetFormatVersion(napi_env env,napi_callback_info info)249 napi_value MediaAssetEditDataNapi::JSSetFormatVersion(napi_env env, napi_callback_info info)
250 {
251     MediaAssetEditDataNapi* obj = nullptr;
252     string formatVersion;
253     CHECK_NULLPTR_RET(GetStringArg(env, info, &obj, EDIT_FORMAT_MAX_LENGTH, formatVersion));
254     obj->SetFormatVersion(formatVersion);
255     RETURN_NAPI_UNDEFINED(env);
256 }
257 
JSSetData(napi_env env,napi_callback_info info)258 napi_value MediaAssetEditDataNapi::JSSetData(napi_env env, napi_callback_info info)
259 {
260     MediaAssetEditDataNapi* obj = nullptr;
261     string data;
262     CHECK_NULLPTR_RET(GetStringArg(env, info, &obj, EDIT_DATA_MAX_LENGTH, data));
263     obj->SetData(data);
264     RETURN_NAPI_UNDEFINED(env);
265 }
266 } // namespace OHOS::Media