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 #include "tone_attrs_napi.h"
17
18 #include "system_sound_log.h"
19 #include "common_napi.h"
20
21 #include "tokenid_kit.h"
22 #include "ipc_skeleton.h"
23 #include "access_token.h"
24 #include "accesstoken_kit.h"
25 #include "ringtone_common_napi.h"
26
27 using OHOS::Security::AccessToken::AccessTokenKit;
28
29 namespace {
30 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_AUDIO_NAPI, "ToneAttrsNapi"};
31 }
32
33 namespace OHOS {
34 namespace Media {
35
36 thread_local napi_ref ToneAttrsNapi::sConstructor_ = nullptr;
37 std::shared_ptr<ToneAttrs> ToneAttrsNapi::sToneAttrs_ = nullptr;
38
ToneAttrsNapi()39 ToneAttrsNapi::ToneAttrsNapi() : env_(nullptr) {}
40
41 ToneAttrsNapi::~ToneAttrsNapi() = default;
42
Init(napi_env env,napi_value exports)43 napi_value ToneAttrsNapi::Init(napi_env env, napi_value exports)
44 {
45 napi_status status;
46 napi_value ctorObj;
47 int32_t refCount = 1;
48
49 napi_property_descriptor tone_attrs_prop[] = {
50 DECLARE_NAPI_FUNCTION("getTitle", GetTitle),
51 DECLARE_NAPI_FUNCTION("setTitle", SetTitle),
52 DECLARE_NAPI_FUNCTION("getFileName", GetFileName),
53 DECLARE_NAPI_FUNCTION("setFileName", SetFileName),
54 DECLARE_NAPI_FUNCTION("getUri", GetUri),
55 DECLARE_NAPI_FUNCTION("getCustomizedType", GetCustomizedType),
56 DECLARE_NAPI_FUNCTION("setCategory", SetCategory),
57 DECLARE_NAPI_FUNCTION("getCategory", GetCategory),
58 };
59
60 status = napi_define_class(env, TONE_ATTRS_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH,
61 Construct, nullptr, sizeof(tone_attrs_prop) / sizeof(tone_attrs_prop[0]),
62 tone_attrs_prop, &ctorObj);
63 if (status == napi_ok) {
64 if (napi_create_reference(env, ctorObj, refCount, &sConstructor_) == napi_ok) {
65 status = napi_set_named_property(env, exports, TONE_ATTRS_NAPI_CLASS_NAME.c_str(), ctorObj);
66 if (status == napi_ok) {
67 return exports;
68 }
69 }
70 }
71
72 return nullptr;
73 }
74
Construct(napi_env env,napi_callback_info info)75 napi_value ToneAttrsNapi::Construct(napi_env env, napi_callback_info info)
76 {
77 napi_status status;
78 napi_value jsThis = nullptr;
79 napi_value thisVar = nullptr;
80
81 status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
82 if (status == napi_ok) {
83 std::unique_ptr<ToneAttrsNapi> obj = std::make_unique<ToneAttrsNapi>();
84 if (obj != nullptr && thisVar != nullptr) {
85 obj->env_ = env;
86 status = napi_wrap(env, thisVar, static_cast<void*>(obj.get()),
87 ToneAttrsNapi::Destructor, nullptr, nullptr);
88 if (status == napi_ok) {
89 obj.release();
90 return thisVar;
91 }
92 }
93 }
94 MEDIA_LOGE("Failed in ToneAttrsNapi::Construct()!");
95 napi_get_undefined(env, &jsThis);
96 return jsThis;
97 }
98
Destructor(napi_env env,void * nativeObject,void * finalize_hint)99 void ToneAttrsNapi::Destructor(napi_env env, void *nativeObject, void *finalize_hint)
100 {
101 ToneAttrsNapi *ToneAttrsHelper = reinterpret_cast<ToneAttrsNapi*>(nativeObject);
102 if (ToneAttrsHelper != nullptr) {
103 ObjectRefMap<ToneAttrsNapi>::DecreaseRef(ToneAttrsHelper);
104 }
105 }
106
NewInstance(napi_env env,std::shared_ptr<ToneAttrs> & nativeToneAttrs,napi_value & out)107 napi_status ToneAttrsNapi::NewInstance(napi_env env, std::shared_ptr<ToneAttrs>& nativeToneAttrs, napi_value& out)
108 {
109 napi_value constructor {};
110 NAPI_CALL_BASE(env, napi_get_reference_value(env, sConstructor_, &constructor), napi_generic_failure);
111 napi_value instance{};
112 NAPI_CALL_BASE(env, napi_new_instance(env, constructor, 0, nullptr, &instance), napi_generic_failure);
113
114 ToneAttrsNapi* toneAttrsNapi{};
115 NAPI_CALL_BASE(env, napi_unwrap(env, instance, reinterpret_cast<void**>(&toneAttrsNapi)), napi_generic_failure);
116 CHECK_AND_RETURN_RET_LOG(toneAttrsNapi != nullptr, napi_invalid_arg, "toneAttrsNapi is nullptr");
117
118 toneAttrsNapi->toneAttrs_ = std::move(nativeToneAttrs);
119 out = instance;
120 return napi_ok;
121 }
122
GetToneAttrs()123 std::shared_ptr<ToneAttrs> ToneAttrsNapi::GetToneAttrs()
124 {
125 return toneAttrs_;
126 }
127
ThrowErrorAndReturn(napi_env env,const std::string & errMsg,int32_t errCode)128 napi_value ToneAttrsNapi::ThrowErrorAndReturn(napi_env env, const std::string& errMsg, int32_t errCode)
129 {
130 napi_value message = nullptr;
131 napi_value code = nullptr;
132 napi_value errVal = nullptr;
133 napi_value errNameVal = nullptr;
134 napi_value result{};
135 napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message);
136 napi_create_error(env, nullptr, message, &errVal);
137 napi_create_int32(env, errCode, &code);
138 napi_set_named_property(env, errVal, "code", code);
139 napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &errNameVal);
140 napi_set_named_property(env, errVal, "BusinessError", errNameVal);
141 napi_throw(env, errVal);
142 napi_get_undefined(env, &result);
143 return result;
144 }
145
VerifySelfSystemPermission()146 bool ToneAttrsNapi::VerifySelfSystemPermission()
147 {
148 Security::AccessToken::FullTokenID selfTokenID = IPCSkeleton::GetSelfTokenID();
149 auto tokenTypeFlag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(static_cast<uint32_t>(selfTokenID));
150 if (tokenTypeFlag == Security::AccessToken::TOKEN_NATIVE ||
151 tokenTypeFlag == Security::AccessToken::TOKEN_SHELL ||
152 Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfTokenID)) {
153 return true;
154 }
155 return false;
156 }
157
GetTitle(napi_env env,napi_callback_info info)158 napi_value ToneAttrsNapi::GetTitle(napi_env env, napi_callback_info info)
159 {
160 ToneAttrsNapi *toneAttrsNapi = nullptr;
161 napi_value jsThis = nullptr;
162 size_t argc = 0;
163 CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
164 ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
165 "No system permission");
166
167 napi_status status = napi_get_cb_info(env, info, &argc, nullptr, &jsThis, nullptr);
168
169 CHECK_AND_RETURN_RET_LOG((status == napi_ok) && (jsThis != nullptr), nullptr, "jsThis is nullptr");
170 napi_unwrap(env, jsThis, reinterpret_cast<void**>(&toneAttrsNapi));
171 CHECK_AND_RETURN_RET_LOG(toneAttrsNapi != nullptr, nullptr, "toneAttrsNapi is nullptr");
172 CHECK_AND_RETURN_RET_LOG(toneAttrsNapi->toneAttrs_ != nullptr, nullptr, "toneAttrs_ is nullptr");
173 napi_value result;
174 napi_create_string_utf8(env,
175 toneAttrsNapi->toneAttrs_->GetTitle().c_str(), NAPI_AUTO_LENGTH, &result);
176 return result;
177 }
178
SetTitle(napi_env env,napi_callback_info info)179 napi_value ToneAttrsNapi::SetTitle(napi_env env, napi_callback_info info)
180 {
181 ToneAttrsNapi *toneAttrsNapi = nullptr;
182 napi_value jsThis = nullptr;
183 size_t argc = 1;
184 napi_value argv[1] = {};
185 CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
186 ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
187 "No system permission");
188
189 napi_status status = napi_get_cb_info(env, info, &argc, argv, &jsThis, nullptr);
190
191 napi_valuetype valueType = napi_undefined;
192 napi_typeof(env, argv[0], &valueType);
193 CHECK_AND_RETURN_RET_LOG(valueType == napi_string, nullptr, "title is not string");
194
195 std::string toneAttrsTitle = CommonNapi::GetStringArgument(env, argv[0]);
196 CHECK_AND_RETURN_RET_LOG(argc == 1 && !toneAttrsTitle.empty(),
197 ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID),
198 "invalid arguments");
199 CHECK_AND_RETURN_RET_LOG((status == napi_ok) && (jsThis != nullptr), nullptr, "jsThis is nullptr");
200
201 napi_unwrap(env, jsThis, reinterpret_cast<void**>(&toneAttrsNapi));
202 CHECK_AND_RETURN_RET_LOG(toneAttrsNapi != nullptr, nullptr, "toneAttrsNapi is nullptr");
203 CHECK_AND_RETURN_RET_LOG(toneAttrsNapi->toneAttrs_ != nullptr, nullptr, "toneAttrs_ is nullptr");
204 toneAttrsNapi->toneAttrs_->SetTitle(toneAttrsTitle);
205 return nullptr;
206 }
207
GetFileName(napi_env env,napi_callback_info info)208 napi_value ToneAttrsNapi::GetFileName(napi_env env, napi_callback_info info)
209 {
210 ToneAttrsNapi *toneAttrsNapi = nullptr;
211 napi_value jsThis = nullptr;
212 size_t argc = 0;
213 CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
214 ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
215 "No system permission");
216
217 napi_status status = napi_get_cb_info(env, info, &argc, nullptr, &jsThis, nullptr);
218 CHECK_AND_RETURN_RET_LOG((status == napi_ok) && (jsThis != nullptr), nullptr, "jsThis is nullptr");
219 napi_unwrap(env, jsThis, reinterpret_cast<void**>(&toneAttrsNapi));
220 CHECK_AND_RETURN_RET_LOG(toneAttrsNapi != nullptr, nullptr, "toneAttrsNapi is nullptr");
221 CHECK_AND_RETURN_RET_LOG(toneAttrsNapi->toneAttrs_ != nullptr, nullptr, "toneAttrs_ is nullptr");
222 napi_value result;
223 napi_create_string_utf8(env,
224 toneAttrsNapi->toneAttrs_->GetFileName().c_str(), NAPI_AUTO_LENGTH, &result);
225 return result;
226 }
227
SetFileName(napi_env env,napi_callback_info info)228 napi_value ToneAttrsNapi::SetFileName(napi_env env, napi_callback_info info)
229 {
230 ToneAttrsNapi *toneAttrsNapi = nullptr;
231 napi_value jsThis = nullptr;
232 size_t argc = 1;
233 napi_value argv[1] = {};
234 CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
235 ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
236 "No system permission");
237
238 napi_status status = napi_get_cb_info(env, info, &argc, argv, &jsThis, nullptr);
239
240 napi_valuetype valueType = napi_undefined;
241 napi_typeof(env, argv[0], &valueType);
242 CHECK_AND_RETURN_RET_LOG(valueType == napi_string, nullptr, "filename is not string");
243
244 std::string toneAttrsFileName = CommonNapi::GetStringArgument(env, argv[0]);
245 CHECK_AND_RETURN_RET_LOG(argc == 1 && !toneAttrsFileName.empty(),
246 ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID),
247 "invalid arguments");
248 CHECK_AND_RETURN_RET_LOG((status == napi_ok) && (jsThis != nullptr), nullptr, "jsThis is nullptr");
249
250 napi_unwrap(env, jsThis, reinterpret_cast<void**>(&toneAttrsNapi));
251 CHECK_AND_RETURN_RET_LOG(toneAttrsNapi != nullptr, nullptr, "toneAttrsNapi is nullptr");
252 CHECK_AND_RETURN_RET_LOG(toneAttrsNapi->toneAttrs_ != nullptr, nullptr, "toneAttrs_ is nullptr");
253 toneAttrsNapi->toneAttrs_->SetFileName(toneAttrsFileName);
254 return nullptr;
255 }
256
GetUri(napi_env env,napi_callback_info info)257 napi_value ToneAttrsNapi::GetUri(napi_env env, napi_callback_info info)
258 {
259 ToneAttrsNapi *toneAttrsNapi = nullptr;
260 napi_value jsThis = nullptr;
261 size_t argc = 0;
262 CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
263 ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
264 "No system permission");
265
266 napi_status status = napi_get_cb_info(env, info, &argc, nullptr, &jsThis, nullptr);
267 CHECK_AND_RETURN_RET_LOG((status == napi_ok) && (jsThis != nullptr), nullptr, "jsThis is nullptr");
268 napi_unwrap(env, jsThis, reinterpret_cast<void**>(&toneAttrsNapi));
269 CHECK_AND_RETURN_RET_LOG(toneAttrsNapi != nullptr, nullptr, "toneAttrsNapi is nullptr");
270 CHECK_AND_RETURN_RET_LOG(toneAttrsNapi->toneAttrs_ != nullptr, nullptr, "toneAttrs_ is nullptr");
271 napi_value result;
272 napi_create_string_utf8(env,
273 toneAttrsNapi->toneAttrs_->GetUri().c_str(), NAPI_AUTO_LENGTH, &result);
274 return result;
275 }
276
GetCustomizedType(napi_env env,napi_callback_info info)277 napi_value ToneAttrsNapi::GetCustomizedType(napi_env env, napi_callback_info info)
278 {
279 ToneAttrsNapi *toneAttrsNapi = nullptr;
280 napi_value jsThis = nullptr;
281 size_t argc = 0;
282 CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
283 ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
284 "No system permission");
285
286 napi_status status = napi_get_cb_info(env, info, &argc, nullptr, &jsThis, nullptr);
287 CHECK_AND_RETURN_RET_LOG((status == napi_ok) && (jsThis != nullptr), nullptr, "jsThis is nullptr");
288 napi_unwrap(env, jsThis, reinterpret_cast<void**>(&toneAttrsNapi));
289 CHECK_AND_RETURN_RET_LOG(toneAttrsNapi != nullptr, nullptr, "toneAttrsNapi is nullptr");
290 CHECK_AND_RETURN_RET_LOG(toneAttrsNapi->toneAttrs_ != nullptr, nullptr, "toneAttrs_ is nullptr");
291 napi_value result;
292 napi_create_int32(env, toneAttrsNapi->toneAttrs_->GetCustomizedType(), &result);
293 return result;
294 }
295
SetCategory(napi_env env,napi_callback_info info)296 napi_value ToneAttrsNapi::SetCategory(napi_env env, napi_callback_info info)
297 {
298 ToneAttrsNapi *toneAttrsNapi = nullptr;
299 napi_value jsThis = nullptr;
300 size_t argc = 1;
301 napi_value argv[1] = {};
302 CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
303 ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
304 "No system permission");
305
306 napi_status status = napi_get_cb_info(env, info, &argc, argv, &jsThis, nullptr);
307
308 napi_valuetype valueType = napi_undefined;
309 napi_typeof(env, argv[0], &valueType);
310
311 bool isCategoryValid = false;
312 int32_t toneAttrsCategory = TONE_CATEGORY_INVALID;
313 napi_get_value_int32(env, argv[0], &toneAttrsCategory);
314 if (toneAttrsCategory == TONE_CATEGORY_RINGTONE || toneAttrsCategory == TONE_CATEGORY_TEXT_MESSAGE ||
315 toneAttrsCategory == TONE_CATEGORY_NOTIFICATION || toneAttrsCategory == TONE_CATEGORY_ALARM) {
316 isCategoryValid = true;
317 }
318 CHECK_AND_RETURN_RET_LOG(argc == 1 && isCategoryValid,
319 ThrowErrorAndReturn(env, NAPI_ERR_INPUT_INVALID_INFO, NAPI_ERR_INPUT_INVALID),
320 "invalid arguments");
321 CHECK_AND_RETURN_RET_LOG((status == napi_ok) && (jsThis != nullptr), nullptr, "jsThis is nullptr");
322
323 napi_unwrap(env, jsThis, reinterpret_cast<void**>(&toneAttrsNapi));
324 CHECK_AND_RETURN_RET_LOG(toneAttrsNapi != nullptr, nullptr, "toneAttrsNapi is nullptr");
325 CHECK_AND_RETURN_RET_LOG(toneAttrsNapi->toneAttrs_ != nullptr, nullptr, "toneAttrs_ is nullptr");
326 toneAttrsNapi->toneAttrs_->SetCategory(toneAttrsCategory);
327 return nullptr;
328 }
329
GetCategory(napi_env env,napi_callback_info info)330 napi_value ToneAttrsNapi::GetCategory(napi_env env, napi_callback_info info)
331 {
332 ToneAttrsNapi *toneAttrsNapi = nullptr;
333 napi_value jsThis = nullptr;
334 size_t argc = 0;
335 CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
336 ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
337 "No system permission");
338
339 napi_status status = napi_get_cb_info(env, info, &argc, nullptr, &jsThis, nullptr);
340 CHECK_AND_RETURN_RET_LOG((status == napi_ok) && (jsThis != nullptr), nullptr, "jsThis is nullptr");
341 napi_unwrap(env, jsThis, reinterpret_cast<void**>(&toneAttrsNapi));
342 CHECK_AND_RETURN_RET_LOG(toneAttrsNapi != nullptr, nullptr, "toneAttrsNapi is nullptr");
343 CHECK_AND_RETURN_RET_LOG(toneAttrsNapi->toneAttrs_ != nullptr, nullptr, "toneAttrs_ is nullptr");
344 napi_value result;
345 napi_create_int32(env, toneAttrsNapi->toneAttrs_->GetCategory(), &result);
346 return result;
347 }
348
349 } // namespace Media
350 } // namespace OHOS