1 /*
2 * Copyright (c) 2022 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 #include "napi_context_common.h"
16
17 namespace OHOS {
18 namespace Security {
19 namespace AccessToken {
20 namespace {
21 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_PRIVACY, "PrivacyContextCommonNapi"};
22 } // namespace
PrivacyAsyncWorkData(napi_env envValue)23 PrivacyAsyncWorkData::PrivacyAsyncWorkData(napi_env envValue)
24 {
25 env = envValue;
26 }
27
~PrivacyAsyncWorkData()28 PrivacyAsyncWorkData::~PrivacyAsyncWorkData()
29 {
30 if (callbackRef != nullptr) {
31 napi_delete_reference(env, callbackRef);
32 callbackRef = nullptr;
33 }
34
35 if (asyncWork != nullptr) {
36 napi_delete_async_work(env, asyncWork);
37 asyncWork = nullptr;
38 }
39 }
40
~PermActiveChangeContext()41 PermActiveChangeContext::~PermActiveChangeContext()
42 {
43 if (callbackRef != nullptr) {
44 napi_delete_reference(env, callbackRef);
45 callbackRef = nullptr;
46 }
47 }
48
PermActiveStatusPtr(const std::vector<std::string> & permList)49 PermActiveStatusPtr::PermActiveStatusPtr(const std::vector<std::string>& permList)
50 : PermActiveStatusCustomizedCbk(permList)
51 {}
52
~PermActiveStatusPtr()53 PermActiveStatusPtr::~PermActiveStatusPtr()
54 {}
55
SetEnv(const napi_env & env)56 void PermActiveStatusPtr::SetEnv(const napi_env& env)
57 {
58 env_ = env;
59 }
60
SetCallbackRef(const napi_ref & ref)61 void PermActiveStatusPtr::SetCallbackRef(const napi_ref& ref)
62 {
63 ref_ = ref;
64 }
65
ActiveStatusChangeCallback(ActiveChangeResponse & result)66 void PermActiveStatusPtr::ActiveStatusChangeCallback(ActiveChangeResponse& result)
67 {
68 uv_loop_s* loop = nullptr;
69 NAPI_CALL_RETURN_VOID(env_, napi_get_uv_event_loop(env_, &loop));
70 if (loop == nullptr) {
71 ACCESSTOKEN_LOG_ERROR(LABEL, "loop instance is nullptr");
72 return;
73 }
74 uv_work_t* work = new (std::nothrow) uv_work_t;
75 if (work == nullptr) {
76 ACCESSTOKEN_LOG_ERROR(LABEL, "insufficient memory for work!");
77 return;
78 }
79 std::unique_ptr<uv_work_t> uvWorkPtr {work};
80 PermActiveStatusWorker* permActiveStatusWorker = new (std::nothrow) PermActiveStatusWorker();
81 if (permActiveStatusWorker == nullptr) {
82 ACCESSTOKEN_LOG_ERROR(LABEL, "insufficient memory for RegisterPermStateChangeWorker!");
83 return;
84 }
85 std::unique_ptr<PermActiveStatusWorker> workPtr {permActiveStatusWorker};
86 permActiveStatusWorker->env = env_;
87 permActiveStatusWorker->ref = ref_;
88 permActiveStatusWorker->result = result;
89 ACCESSTOKEN_LOG_DEBUG(LABEL,
90 "result: tokenID = %{public}d, permissionName = %{public}s, type = %{public}d",
91 result.tokenID, result.permissionName.c_str(), result.type);
92 permActiveStatusWorker->subscriber = this;
93 work->data = reinterpret_cast<void *>(permActiveStatusWorker);
94 NAPI_CALL_RETURN_VOID(env_,
95 uv_queue_work(loop, work, [](uv_work_t* work) {}, UvQueueWorkActiveStatusChange));
96 uvWorkPtr.release();
97 workPtr.release();
98 }
99
UvQueueWorkActiveStatusChange(uv_work_t * work,int status)100 void UvQueueWorkActiveStatusChange(uv_work_t* work, int status)
101 {
102 (void)status;
103 if (work == nullptr || work->data == nullptr) {
104 ACCESSTOKEN_LOG_ERROR(LABEL, "work == nullptr || work->data == nullptr");
105 return;
106 }
107 std::unique_ptr<uv_work_t> uvWorkPtr {work};
108 PermActiveStatusWorker* permActiveStatusData = reinterpret_cast<PermActiveStatusWorker*>(work->data);
109 std::unique_ptr<PermActiveStatusWorker> workPtr {permActiveStatusData};
110 napi_value result = nullptr;
111 NAPI_CALL_RETURN_VOID(permActiveStatusData->env,
112 napi_create_array(permActiveStatusData->env, &result));
113 if (!ConvertActiveChangeResponse(permActiveStatusData->env, result, permActiveStatusData->result)) {
114 ACCESSTOKEN_LOG_ERROR(LABEL, "ConvertActiveChangeResponse failed");
115 return;
116 }
117 napi_value undefined = nullptr;
118 napi_value callback = nullptr;
119 napi_value resultout = nullptr;
120 NAPI_CALL_RETURN_VOID(permActiveStatusData->env,
121 napi_get_undefined(permActiveStatusData->env, &undefined));
122 NAPI_CALL_RETURN_VOID(permActiveStatusData->env,
123 napi_get_reference_value(permActiveStatusData->env, permActiveStatusData->ref, &callback));
124 NAPI_CALL_RETURN_VOID(permActiveStatusData->env,
125 napi_call_function(permActiveStatusData->env, undefined, callback, 1, &result, &resultout));
126 }
127
ConvertActiveChangeResponse(napi_env env,napi_value value,const ActiveChangeResponse & result)128 bool ConvertActiveChangeResponse(napi_env env, napi_value value, const ActiveChangeResponse& result)
129 {
130 napi_value element;
131 NAPI_CALL_BASE(env, napi_create_uint32(env, result.tokenID, &element), false);
132 NAPI_CALL_BASE(env, napi_set_named_property(env, value, "tokenId", element), false);
133 element = nullptr;
134 NAPI_CALL_BASE(env, napi_create_string_utf8(env, result.permissionName.c_str(),
135 NAPI_AUTO_LENGTH, &element), false);
136 NAPI_CALL_BASE(env, napi_set_named_property(env, value, "permissionName", element), false);
137 element = nullptr;
138 NAPI_CALL_BASE(env, napi_create_string_utf8(env, result.deviceId.c_str(),
139 NAPI_AUTO_LENGTH, &element), false);
140 NAPI_CALL_BASE(env, napi_set_named_property(env, value, "deviceId", element), false);
141 element = nullptr;
142 NAPI_CALL_BASE(env, napi_create_int32(env, result.type, &element), false);
143 NAPI_CALL_BASE(env, napi_set_named_property(env, value, "activeStatus", element), false);
144 return true;
145 }
146 } // namespace AccessToken
147 } // namespace Security
148 } // namespace OHOS