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_haptics_attrs_napi.h"
17 
18 #include "media_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, "ToneHapticsAttrsNapi"};
31 }
32 
33 namespace OHOS {
34 namespace Media {
35 
36 thread_local napi_ref ToneHapticsAttrsNapi::sConstructor_ = nullptr;
37 
ToneHapticsAttrsNapi()38 ToneHapticsAttrsNapi::ToneHapticsAttrsNapi() : env_(nullptr) {}
39 
40 ToneHapticsAttrsNapi::~ToneHapticsAttrsNapi() = default;
41 
Init(napi_env env,napi_value exports)42 napi_value ToneHapticsAttrsNapi::Init(napi_env env, napi_value exports)
43 {
44     napi_status status;
45     napi_value ctorObj;
46     int32_t refCount = 1;
47 
48     napi_property_descriptor tone_haptics_attrs_prop[] = {
49         DECLARE_NAPI_FUNCTION("getUri", GetUri),
50         DECLARE_NAPI_FUNCTION("getTitle", GetTitle),
51         DECLARE_NAPI_FUNCTION("getFileName", GetFileName),
52     };
53 
54     status = napi_define_class(env, TONE_HAPTICS_ATTRS_NAPI_CLASS_NAME.c_str(), NAPI_AUTO_LENGTH,
55         Construct, nullptr, sizeof(tone_haptics_attrs_prop) / sizeof(tone_haptics_attrs_prop[0]),
56         tone_haptics_attrs_prop, &ctorObj);
57     if (status == napi_ok) {
58         if (napi_create_reference(env, ctorObj, refCount, &sConstructor_) == napi_ok) {
59             status = napi_set_named_property(env, exports, TONE_HAPTICS_ATTRS_NAPI_CLASS_NAME.c_str(), ctorObj);
60             if (status == napi_ok) {
61                 return exports;
62             }
63         }
64     }
65 
66     return nullptr;
67 }
68 
Construct(napi_env env,napi_callback_info info)69 napi_value ToneHapticsAttrsNapi::Construct(napi_env env, napi_callback_info info)
70 {
71     napi_status status;
72     napi_value jsThis = nullptr;
73     napi_value thisVar = nullptr;
74 
75     status = napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
76     if (status == napi_ok && thisVar != nullptr) {
77         std::unique_ptr<ToneHapticsAttrsNapi> obj = std::make_unique<ToneHapticsAttrsNapi>();
78         if (obj != nullptr) {
79             obj->env_ = env;
80             status = napi_wrap(env, thisVar, static_cast<void*>(obj.get()), ToneHapticsAttrsNapi::Destructor,
81                 nullptr, nullptr);
82             if (status == napi_ok) {
83                 obj.release();
84                 return thisVar;
85             }
86         }
87     }
88     MEDIA_LOGE("Failed in ToneHapticsAttrsNapi::Construct()!");
89     napi_get_undefined(env, &jsThis);
90     return jsThis;
91 }
92 
Destructor(napi_env env,void * nativeObject,void * finalize_hint)93 void ToneHapticsAttrsNapi::Destructor(napi_env env, void *nativeObject, void *finalize_hint)
94 {
95     if (nativeObject != nullptr) {
96         delete reinterpret_cast<ToneHapticsAttrsNapi*>(nativeObject);
97     }
98 }
99 
NewInstance(napi_env env,std::shared_ptr<ToneHapticsAttrs> & nativeToneHapticsAttrs,napi_value & out)100 napi_status ToneHapticsAttrsNapi::NewInstance(napi_env env, std::shared_ptr<ToneHapticsAttrs> &nativeToneHapticsAttrs,
101     napi_value &out)
102 {
103     napi_value constructor{};
104     NAPI_CALL_BASE(env, napi_get_reference_value(env, sConstructor_, &constructor), napi_generic_failure);
105     napi_value instance{};
106     NAPI_CALL_BASE(env, napi_new_instance(env, constructor, 0, nullptr, &instance), napi_generic_failure);
107 
108     ToneHapticsAttrsNapi* toneHapticsAttrsNapi{};
109     NAPI_CALL_BASE(env, napi_unwrap(env, instance, reinterpret_cast<void**>(&toneHapticsAttrsNapi)),
110         napi_generic_failure);
111     CHECK_AND_RETURN_RET_LOG(toneHapticsAttrsNapi != nullptr, napi_invalid_arg, "toneHapticsAttrsNapi is nullptr");
112 
113     toneHapticsAttrsNapi->toneHapticsAttrs_ = std::move(nativeToneHapticsAttrs);
114     out = instance;
115     return napi_ok;
116 }
117 
ThrowErrorAndReturn(napi_env env,const std::string & errMsg,int32_t errCode)118 napi_value ToneHapticsAttrsNapi::ThrowErrorAndReturn(napi_env env, const std::string &errMsg, int32_t errCode)
119 {
120     napi_value message = nullptr;
121     napi_value code = nullptr;
122     napi_value errVal = nullptr;
123     napi_value errNameVal = nullptr;
124     napi_value result{};
125     napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message);
126     napi_create_error(env, nullptr, message, &errVal);
127     napi_create_int32(env, errCode, &code);
128     napi_set_named_property(env, errVal, "code", code);
129     napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &errNameVal);
130     napi_set_named_property(env, errVal, "BusinessError", errNameVal);
131     napi_throw(env, errVal);
132     napi_get_undefined(env, &result);
133     return result;
134 }
135 
VerifySelfSystemPermission()136 bool ToneHapticsAttrsNapi::VerifySelfSystemPermission()
137 {
138     Security::AccessToken::FullTokenID selfTokenID = IPCSkeleton::GetSelfTokenID();
139     auto tokenTypeFlag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(static_cast<uint32_t>(selfTokenID));
140     if (tokenTypeFlag == Security::AccessToken::TOKEN_NATIVE ||
141         tokenTypeFlag == Security::AccessToken::TOKEN_SHELL ||
142         Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfTokenID)) {
143         return true;
144     }
145     return false;
146 }
147 
GetUri(napi_env env,napi_callback_info info)148 napi_value ToneHapticsAttrsNapi::GetUri(napi_env env, napi_callback_info info)
149 {
150     ToneHapticsAttrsNapi *toneHapticsAttrsNapi = nullptr;
151     napi_value jsThis = nullptr;
152     size_t argc = 0;
153     CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
154         ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
155         "No system permission");
156 
157     napi_status status = napi_get_cb_info(env, info, &argc, nullptr, &jsThis, nullptr);
158     CHECK_AND_RETURN_RET_LOG((status == napi_ok) && (jsThis != nullptr), nullptr, "jsThis is nullptr");
159     napi_unwrap(env, jsThis, reinterpret_cast<void**>(&toneHapticsAttrsNapi));
160     CHECK_AND_RETURN_RET_LOG(toneHapticsAttrsNapi != nullptr, nullptr, "toneAttrsNapi is nullptr");
161     CHECK_AND_RETURN_RET_LOG(toneHapticsAttrsNapi->toneHapticsAttrs_ != nullptr, nullptr,
162         "toneHapticsAttrs_ is nullptr");
163     napi_value result;
164     napi_create_string_utf8(env, toneHapticsAttrsNapi->toneHapticsAttrs_->GetUri().c_str(),
165         NAPI_AUTO_LENGTH, &result);
166     return result;
167 }
168 
GetTitle(napi_env env,napi_callback_info info)169 napi_value ToneHapticsAttrsNapi::GetTitle(napi_env env, napi_callback_info info)
170 {
171     ToneHapticsAttrsNapi *toneHapticsAttrsNapi = nullptr;
172     napi_value jsThis = nullptr;
173     size_t argc = 0;
174     CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
175         ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
176         "No system permission");
177 
178     napi_status status = napi_get_cb_info(env, info, &argc, nullptr, &jsThis, nullptr);
179     CHECK_AND_RETURN_RET_LOG((status == napi_ok) && (jsThis != nullptr), nullptr, "jsThis is nullptr");
180     napi_unwrap(env, jsThis, reinterpret_cast<void**>(&toneHapticsAttrsNapi));
181     CHECK_AND_RETURN_RET_LOG(toneHapticsAttrsNapi != nullptr, nullptr, "toneAttrsNapi is nullptr");
182     CHECK_AND_RETURN_RET_LOG(toneHapticsAttrsNapi->toneHapticsAttrs_ != nullptr, nullptr,
183         "toneHapticsAttrs_ is nullptr");
184     napi_value result;
185     napi_create_string_utf8(env, toneHapticsAttrsNapi->toneHapticsAttrs_->GetTitle().c_str(),
186         NAPI_AUTO_LENGTH, &result);
187     return result;
188 }
189 
GetFileName(napi_env env,napi_callback_info info)190 napi_value ToneHapticsAttrsNapi::GetFileName(napi_env env, napi_callback_info info)
191 {
192     ToneHapticsAttrsNapi *toneHapticsAttrsNapi = nullptr;
193     napi_value jsThis = nullptr;
194     size_t argc = 0;
195     CHECK_AND_RETURN_RET_LOG(VerifySelfSystemPermission(),
196         ThrowErrorAndReturn(env, NAPI_ERR_PERMISSION_DENIED_INFO, NAPI_ERR_PERMISSION_DENIED),
197         "No system permission");
198 
199     napi_status status = napi_get_cb_info(env, info, &argc, nullptr, &jsThis, nullptr);
200     CHECK_AND_RETURN_RET_LOG((status == napi_ok) && (jsThis != nullptr), nullptr, "jsThis is nullptr");
201     napi_unwrap(env, jsThis, reinterpret_cast<void**>(&toneHapticsAttrsNapi));
202     CHECK_AND_RETURN_RET_LOG(toneHapticsAttrsNapi != nullptr, nullptr, "toneAttrsNapi is nullptr");
203     CHECK_AND_RETURN_RET_LOG(toneHapticsAttrsNapi->toneHapticsAttrs_ != nullptr, nullptr,
204         "toneHapticsAttrs_ is nullptr");
205     napi_value result;
206     napi_create_string_utf8(env, toneHapticsAttrsNapi->toneHapticsAttrs_->GetFileName().c_str(),
207         NAPI_AUTO_LENGTH, &result);
208     return result;
209 }
210 } // namespace Media
211 } // namespace OHOS